Action View Record Identifier¶ ↑
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>
在这两种情况下,包装 DOM 元素的 id 和 class 都是自动生成的,遵循 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 | = | "new" |
实例公共方法
dom_class(record_or_class, prefix = nil) Link
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) Link
DOM id 约定是使用对象或类的单数形式,后面跟着一个下划线。如果没有找到 id,则用“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"
# 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_target(*objects) Link
DOM target 约定是将任意数量的参数连接成一个字符串。记录会通过 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"