2013-01-15 44 views
0

我有一个List模型。列表中嵌入了标签(使用Mongoid)。当用户创建列表时,他可以通过文本字段中的逗号分隔列表指定相关标签。accep_nested_attributes_for:tags?通过关联分割和存储逗号分隔标签

如何通过List关联存储标签?我可以使用List模型中的accepts_nested_attributes_for:tags来做到吗,还是必须预先处理标签字符串?

这是我到目前为止。如何处理标记字符串,将其拆分并将每个标记单独存储在列表中的嵌入标记文档中?

列表控制器:

class ListsController < ApplicationController 
    def new 
    @list = List.new 

    respond_to do |format| 
     format.html # new.html.erb 
     format.json { render json: @list } 
    end 
    end 

    def create 
    list_params = params[:list] 
    list_params[:user_id] = current_user.id 
    @list = List.new(list_params) 
    if @list.save 
    redirect_to @list, notice: 'List was successfully created.' 
    else 
     render action: "new" 
    end 
    end 
end 

列表创建表单

= form_for @list do |f| 
    - if @list.errors.any? 
    #error_explanation 
     %h2= "#{pluralize(@list.errors.count, "error")} prohibited this list from being saved:" 
     %ul 
     - @list.errors.full_messages.each do |msg| 
      %li= msg 

    .field 
    = f.label :name 
    = f.text_field :name 
    .field 
    = f.label :description 
    = f.text_field :description 
    .field 
    = f.fields_for :tags do |t| 
     = t.label :tags 
     = t.text_field :name 
    .actions 
    = f.submit 'Save' 

列表模型

class List 
    include Mongoid::Document 
    include Mongoid::Timestamps 
    field :name 
    field :description 
    embeds_many :items 
    embeds_many :comments 
    embeds_many :tags 
    belongs_to :user 

    accepts_nested_attributes_for :tags 

标签模型

class Tag 
    include Mongoid::Document 
    field :name 
    has_one :list 
end 

编辑根据杰夫的建议

列表控制器最终看。

def create 
    tags = params[:tags][:name] 
    list = params[:list] 
    list[:user_id] = current_user.id 
    @list = List.new(list) 
    tags.gsub("\s","").split(",").each do |tag_name| 
     @list.tags.new(:name => tag_name) 
    end 
    if @list.save 
    redirect_to @list, notice: 'List was successfully created.' 
    else 
     render action: "new" 
    end 
    end 

回答

1

如果我理解正确的话,这就是我想你想做的事:

你的,因为它的观点是会显示一个标签名称字段为每个标签,但目前还没有相关的变量,在创建时间所以我认为它只是不显示任何东西。

当使用:has_many时,会有一个很好的小函数,它将被称为List.tag_ids的轨道为您创建。由于我不熟悉它,因此我认为:embeds_many的功能是:has_many的超集。这一点是,如果你可以提供某种形式收集id,那么你就完成了。一组复选框可以工作,或多选。这里是复选框可能是什么样子:

= hidden_field_tag "list[tag_ids][]" 
- Tags.all.each do |t| 
    = check_box_tag "list[tag_ids][]", t.id, t.list == @list, id: "list_tag_ids_#{t.id}" 
    = label_tag "list_tag_ids_#{t.id}", t.name 

我问类似的东西在这里:

Rails: How do I transactionally add a has_many association to an existing model?

然而,这是不是你问什么。您可以通过使用JavaScript实现通过名称关联标签的表单。这可能会很好,但它会有点棘手。

假设没有javascript,如果您在视图中输入名称作为逗号分隔列表,则需要在控制器中解析它。与此相似:

查看:

label_tag :tags 
text_field_tag :tags 

控制器:

... 
@list = List.new(list_params) 
params[:tags].gsub("\s","").split(",").each do |tag_name| 
    tag = Tag.find_by_name(tag_name) 
    @list.tags << tag if tag 
if @list.save 
... 

我建议化妆使用嵌套属性的解决方案中没有。我认为他们不适合你。当您尝试更新嵌套模型的属性时会使用它们,但您只是试图创建关联。

我希望有帮助。

+0

谢谢杰夫,这确实有很大帮助。我发布了一个基于你的帮助的最终解决方案的编辑。非常感激! – aressidi

+0

啊......我的印象是标签已经被创建了。如果您有创建和未创建的标签混合,您可能需要考虑“@ list.tags.find_or_initialize_by_name(tag_name)”。 – Geoff

+0

哦,等等,我认为只能找到现有的标签关联,而不是所有的标签。没关系! – Geoff