Spec-Zone.ru › Ruby on Rails 8.1

модуль ActionView::RecordIdentifier

Идентификатор записи Action View

RecordIdentifier инкапсулирует методы, используемые различными помощниками ActionView для связывания записей с элементами DOM.

Рассмотрим, например, следующий код формы для публикации:

<%= form_with(model: post) do |f| %>
  <%= f.text_field :body %>
<% end %>

Когда post — новый, не сохранённый экземпляр ActiveRecord::Base, в результате получается следующий HTML:

<form class="new_post" id="new_post" action="/posts" accept-charset="UTF-8" method="post">
  <input type="text" name="post[body]" id="post_body" />
</form>

Когда post — сохранённый экземпляр ActiveRecord::Base, в результате получается следующий HTML:

<form class="edit_post" id="edit_post_42" action="/posts/42" accept-charset="UTF-8" method="post">
  <input type="text" value="What a wonderful world!" name="post[body]" id="post_body" />
</form>

В обоих случаях id и class оборачивающего элемента DOM генерируются автоматически в соответствии с соглашениями об именовании, инкапсулированными методами RecordIdentifier dom_id и dom_class:

dom_id(Post)             # => "new_post"
dom_class(Post)          # => "post"
dom_id(Post.new)         # => "new_post"
dom_class(Post.new)      # => "post"
dom_id(Post.find 42)     # => "post_42"
dom_class(Post.find 42)  # => "post"

Обратите внимание, что для работы этих методов не требуется, чтобы Post был подклассом ActiveRecord::Base. Подойдёт любой класс Post, если его экземпляры отвечают на вызовы to_key и model_name, при условии, что model_name отвечает на вызов param_key. Например:

class Post
  attr_accessor :to_key

  def model_name
    OpenStruct.new param_key: 'post'
  end

  def self.find(id)
    new.tap { |post| post.to_key = [id] }
  end
end

Константы

JOIN
NEW

Открытые методы экземпляра

dom_class (record_or_class, prefix = nil) Показать исходный код
# File actionview/lib/action_view/record_identifier.rb, line 78
def dom_class(record_or_class, prefix = nil)
  singular = model_name_from_record_or_class(record_or_class).param_key
  prefix ? "#{prefix}#{JOIN}#{singular}" : singular
end

Согласно соглашению, в качестве класса DOM используется форма единственного числа имени объекта или класса.

dom_class(post)   # => "post"
dom_class(Person) # => "person"

Если в одном и том же представлении нужно обратиться к нескольким экземплярам одного класса, можно добавить префикс к dom_class:

dom_class(post, :edit)   # => "edit_post"
dom_class(Person, :edit) # => "edit_person"
dom_id (record_or_class, prefix = nil) Показать исходный код
# File actionview/lib/action_view/record_identifier.rb, line 93
def dom_id(record_or_class, prefix = nil)
  raise ArgumentError, "dom_id must be passed a record_or_class as the first argument, you passed #{record_or_class.inspect}" unless record_or_class

  record_id = record_key_for_dom_id(record_or_class) unless record_or_class.is_a?(Class)
  if record_id
    "#{dom_class(record_or_class, prefix)}#{JOIN}#{record_id}"
  else
    dom_class(record_or_class, prefix || NEW)
  end
end

Согласно соглашению, идентификатор DOM образуется из формы единственного числа имени объекта или класса, за которой после подчёркивания следует идентификатор. Если идентификатор не найден, вместо него используется префикс «new_».

dom_id(Post.find(45)) # => "post_45"
dom_id(Post)          # => "new_post"

Если в одном и том же представлении нужно обратиться к нескольким экземплярам одного класса, можно добавить префикс к dom_id:

dom_id(Post.find(45), :edit) # => "edit_post_45"
dom_id(Post, :custom)        # => "custom_post"
dom_target (*objects) Показать исходный код
# File actionview/lib/action_view/record_identifier.rb, line 111
def dom_target(*objects)
  objects.map! do |object|
    case object
    when Symbol, String
      object
    when Class
      dom_class(object)
    else
      dom_id(object)
    end
  end
  objects.join(JOIN)
end

Согласно соглашению, целевой элемент DOM формируется конкатенацией любого количества параметров в строку. Записи обрабатываются методом dom_id, а строки и символы сохраняются без изменений.

dom_target(Post.find(45))                  # => "post_45"
dom_target(Post.find(45), :edit)           # => "post_45_edit"
dom_target(Post.find(45), :edit, :special) # => "post_45_edit_special"
dom_target(Post.find(45), Comment.find(1)) # => "post_45_comment_1"

Закрытые методы экземпляра

record_key_for_dom_id (record) Показать исходный код
# File actionview/lib/action_view/record_identifier.rb, line 134
def record_key_for_dom_id(record) # :doc:
  key = convert_to_model(record).to_key
  key && key.all? ? key.join(JOIN) : nil
end

Возвращает строковое представление ключевого атрибута или атрибутов, подходящее для использования в идентификаторе DOM HTML. При необходимости этот метод можно переопределить, чтобы настроить формат строки, генерируемой по умолчанию. Если нужно извлечь ключ из dom_id, чтобы выполнить запрос к соответствующей записи в базе данных, следует написать вспомогательный метод, например «person_record_from_dom_id», который извлечёт ключ либо на основе реализации по умолчанию (она просто объединяет все ключевые атрибуты символом «_»), либо на основе переопределённой вами версии метода. По умолчанию эта реализация передаёт строку ключа методу, который заменяет все недопустимые в идентификаторах DOM символы допустимыми. Если вы переопределяете этот метод, самостоятельно убедитесь, что ваши идентификаторы DOM допустимы.

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API