2010-10-22 107 views
4

我有一個表格,讓我創造新的博客文章,我希望能夠創建相同的形式新類別HABTM關係和accepts_nested_attributes_for

我有帖子和類別之間的關係,這就是爲什麼我遇到麻煩。

我有以下2種型號:

class Post < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
    attr_accessible :title, :body, :category_ids 

    accepts_nested_attributes_for :categories # should this be singular? 
end 

class Category < ActiveRecord::Base 
    has_and_belongs_to_many :posts 
    attr_accessible :name 
end 

我的形式讓我從一堆現有類別中挑選,或創建一個全新的。我的表格如下。

# using simple_form gem 
.inputs 
    = f.input :title 
    = f.input :body 

    # the line below lets me choose from existing categories 
    = f.association :categories, :label => 'Filed Under' 

    # I was hoping that the code below would let me create new categories 
    = f.fields_for :category do |builder| 
    = builder.label :content, "Name" 
    = builder.text_field :content 

當我提交我的表單時,它會被處理,但不會創建新的類別。我的命令提示符下輸出告訴我:

WARNING: Can't mass-assign protected attributes: category 

但是,如果我添加attr_accessible :category,我得到錯誤消息的大胖子崩潰「未知屬性:類別」。

如果我將fields_for target更改爲:categories(而不是category),那麼我的表單甚至不會顯示。

我花了一段時間試圖弄清楚這一點,並觀察了nested_models和simple_form上最近的railscasts,但無法解決我的問題。

如果我使用has_many:through關係(使用連接模型)而不是habtm,會更容易嗎?

+0

http://stackoverflow.com/a/12961298/1446551 – 2013-04-30 07:48:05

回答

1

感謝所有回答的人。經過多次試驗和錯誤,我設法提出了一個解決方案。

首先,我從一個HABTM切換到的has_many:通過關係,叫我加入模型categorization.rb(而不是categorizations_posts.rb) - 注:下文詳述的修復很可能會用工作HABTM太:

步驟1:我改變了我的模型看起來像這樣:

# post.rb 
class Post < ActiveRecord::Base 
    has_many :categorizations 
    has_many :categories, :through => :categorizations 
    attr_accessible :title, :body, :category_ids 
    accepts_nested_attributes_for :categories 
end 

#category.rb 
class Category < ActiveRecord::Base 
    has_many :categorizations 
    has_many :posts, :through => :categorizations 
    attr_accessible :name, :post_ids 
end 

#categorization.rb 
class Categorization < ActiveRecord::Base 
    belongs_to :post 
    belongs_to :category 
end 

從上面樁模型:很明顯,訪問命名:CA tegory_ids必須存在,如果你想使選擇多個現有類別,但你需要的存取方法創建新類別...我不知道。

第2步:我改變了我的看法,看起來像這樣:

-# just showing the relevent parts 
= fields_for :category do |builder| 
    = builder.label :name, "Name" 
    = builder.text_field :name 

從上面的視圖代碼,一定要注意使用fields_for :category,而不是有點直觀重要的fields_for :categories_attributes

步驟3 最後,我在控制器中添加了一些代碼:

# POST /posts 
# POST /posts.xml 
def create 
    @post = Post.new(params[:post]) 
    @category = @post.categories.build(params[:category]) unless params[:category][:name].blank? 
    # stuff removed 
end 


def update 
    @post = Post.find(params[:id]) 
    @category = @post.categories.build(params[:category]) unless params[:category][:name].blank? 
    # stuff removed 
end 

現在,當我創建一個新的崗位,我可以同時從選擇菜單中選擇多個現有類別同時創建一個全新的品類 - 它不是一個或最其它

的情況下,

有一個微小的錯誤編輯和更新現有員額其中發生;在這種情況下,它不會讓我同時創建一個新類別選擇多個現有類別 - 如果我嘗試同時執行這兩個類別,那麼只有現有類別與該帖子相關聯,並且全新的類別被拒絕(沒有錯誤信息)。 我可以通過編輯帖子兩次,一次創建新的類別(自動關聯它與帖子),然後第二次從菜單中選擇一些額外的現有類別 - 就像我說的這不是一個大問題,因爲它所有的作品真的很好,否則,我的用戶可以適應這些限制

無論如何,我希望這可以幫助別人。

阿門。

-1

也許你應該(不testet)嘗試:

attr_accessible :category_attributes 

而且HBTM關係的arent真正recommened ...但我使用它們在我自己的:P

+0

我試過這個,也使用categories_attributes(在模型和表單中),都沒有工作。你會推薦使用has_many:through代替嗎?我認爲我會立即行動 – stephenmurdoch 2010-10-22 10:54:44

+0

Baybe你在用non-hbtm解決這個問題上更快:P – Lichtamberg 2010-10-22 10:58:14

0

在你的表格你應該爲每個類別渲染fields_for一次(每個帖子可以有多個類別,因此是habtm關係)。嘗試類似:

- for category in @post.categories 
    = fields_for "post[categories_attributes][#{category.new_record? ? category.object_id : category.id}]", category do |builder| 
    = builder.hidden_field :id unless category.new_record? 
    = builder.label :content, "Name" 
    = builder.text_field :content 
+0

不錯的想法,但沒有用 - 我修復了問題,一旦我找到答案,已停止啓動 – stephenmurdoch 2010-10-22 12:53:20

+0

啊,好的。我期待着看到你的解決方案... – Yannis 2010-10-22 13:36:43

0

我讓我的應用程序和我的嵌套窗體與HABTM一起工作。 我的模式是:

class UserProfile < ActiveRecord::Base 

    attr_accessible :name, :profession 

    has_and_belongs_to_many :cities 

    belongs_to :user 

    attr_accessible :city_ids, :cities 
    def self.check_city(user,city) 

    user.cities.find_by_id(city.id).present? 

    end 

end 

class City < ActiveRecord::Base 

    attr_accessible :city_name 

    has_and_belongs_to_many :user_profiles 

end 

在我的表單中我有:

-# just showing the relevent parts 


= f.fields_for :cities do|city| 

      = city.text_field :city_name 

而在我的控制器:

def create 

    params[:user_profile][:city_ids] ||= [] 
    if params[:user_profile][:cities][:city_name].present? 
     @city= City.create(:city_name=>params[:user_profile][:cities][:city_name]) 
     @city.save 
     params[:user_profile][:city_ids] << @city.id 
    end 

    @user=current_user 
    params[:user_profile].delete(:cities) 
    @user_profile = @user.build_user_profile(params[:user_profile]) 

    respond_to do |format| 
     if @user_profile.save 

     format.html { redirect_to @user_profile, notice: 'User profile was successfully created.' } 
     format.json { render json: @user_profile, status: :created, location: @user_profile } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @user_profile.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

def update 

    params[:user_profile][:city_ids] ||= [] 
    if params[:user_profile][:cities][:city_name].present? 
     @city= City.create(:city_name=>params[:user_profile][:cities][:city_name]) 
     @city.save 
     params[:user_profile][:city_ids] << @city.id 
    end 
    @user=current_user 
    params[:user_profile].delete(:cities) 
    @user_profile = @user.user_profile 

    respond_to do |format| 
     if @user_profile.update_attributes(params[:user_profile]) 

     format.html { redirect_to @user_profile, notice: 'User profile was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: "edit" } 
     format.json { render json: @user_profile.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

此代碼的工作。