Ruby on Rails:在 gem 上充当可标记的角色,在模型中使用上下文

Ruby on Rails: Acts as taggable on gem, working with context in model

我想知道是否有人可以帮助我理解文档中的这一部分:

With the defined context in model, you have multiple new methods at disposal to manage and view the tags in the context. For example, with :skill context these methods are added to the model: skill_list(and skill_list.add, skill_list.remove skill_list=), skills(plural), skill_counts.

我有这个:

型号:

class Project < ActiveRecord::Base
  acts_as_taggable # Alias for acts_as_taggable_on :tags
  acts_as_taggable_on :item
end

控制器:

def project_params
  params.require(:project).permit(
    :user_id, :tag_list)
end

查看

<%= f.text_field :tag_list %> <!-- wrapped in a simple_form -->

所以我的问题是...这是否意味着,如果我的模型中有 :items,我可以将所有 :tag_list 替换为 :item_list?从现在开始只使用 item_list 吗?我试过了,但它产生的结果与我目前的结果不一样……也许我在某个地方搞砸了,但这 "theoretically" 正确吗?

谢谢

奖金:

所以最终,如果我要标记不止一件东西:

acts_as_taggable_on :item, :more_taggable_item

我可以把这个放在我的强参数中

params.require(:project).permit(
    :user_id, :tag_list, :more_taggable_item_list)

然后我就可以在我的视图中使用它了:

<%= f.text_field :more_taggable_item_list %>

我想您必须像文档中那样使用复数形式。所以 :items 而不是 :item:more_taggable_items 而不是 :more_taggable_item。 Rails 在创建正确的命名约定时提供了许多可用于 gems 的功能,好的 gems 会利用它。

# model
class Project < ActiveRecord::Base
  acts_as_taggable_on :items, :more_taggable_items
end

# params
def project_params
  params.require(:project).permit(
    :user_id, :item_list, :more_taggable_item_list)
end

# view
<%= f.text_field :item_list %> 
<%= f.text_field :more_taggable_item_list %>

你是对的。如果您在模型中使用默认 acts_as_taggable(或显式 acts_as_taggable_on :tags),则 gem 将动态定义以下方法:tag_listtag_list=tags, tag_counts.

如果使用acts_as_taggable_on :items代替(注意复数,如@smallbutton.com所说),将动态定义以下方法:item_listitem_list=items, item_counts.

所以在你的情况下,你不需要第一个 acts_as_taggable。仅使用 acts_as_taggable_on :items, :more_taggable_items。然后,您可以在控制器和视图中使用 item_listmore_taggable_item_list,而不是 tag_list.


PS:供参考,参见gem中的acts_as_taggable is defined

# This is an alias for calling <tt>acts_as_taggable_on :tags</tt>.
def acts_as_taggable
  acts_as_taggable_on :tags
end

method generation 有点复杂,但基本上它会遍历您的 acts_as_taggable_on 参数,并用它们定义方法:

# Loop over [:items, :more_taggable_items]
tag_types.map(&:to_s).each do |tags_type|
  tag_type = tags_type.to_s.singularize # 'item', 'more_taggable_item'
  # ...

  taggable_mixin.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    # Define item_list, more_taggable_item_list
    def #{tag_type}_list
      tag_list_on('#{tags_type}')
    end

    # ...
  RUBY
end