2013-01-15 42 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