HABTM关系和accepts_nested_attributes_for [英] HABTM relationships and accepts_nested_attributes_for

查看:90
本文介绍了HABTM关系和accepts_nested_attributes_for的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表单,可以让我创建新博客帖子,并且我希望能够从同一表单中创建新类别.

I have a form that lets me create new blog posts and I'd like to be able to create new categories from the same form.

我在帖子和类别之间有一个habtm关系,这就是为什么我对此感到麻烦.

I have a habtm relationship between posts and categories, which is why I'm having trouble with this.

我有以下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

我的表格可让我从一堆现有类别中进行选择或创建一个全新的类别.我的表格如下.

My form lets me pick from a bunch of existing categories or create a brand new one. My form is as follows.

# 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

提交表单时,该表单将得到处理,但不会创建新类别.我的命令提示符输出告诉我:

When I submit my form, it gets processed but the new category is not created. My command prompt output tells me:

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

但是,如果我添加attr_accessible :category,则会收到错误消息未知属性:类别"的严重崩溃.

But, if I add attr_accessible :category, I get a big fat crash with error message "unknown attribute: category".

如果我将fields_for目标更改为:categories(而不是category),那么我的表单甚至不会显示.

If I change the fields_for target to :categories (instead of category) then my form doesn't even display.

我花了一段时间尝试解决这个问题,并观看了关于nested_models和simple_form的最新文章,但无法解决我的问题.

I've spent a while trying to figure this out, and watched the recent railscasts on nested_models and simple_form but couldn't get my problem fixed.

如果我使用has_many:through关系(带有连接模型)而不是habtm,这会更容易吗?

Would this be easier if I was using a has_many :through relationship (with a join model) instead of a habtm?

推荐答案

感谢所有回答的人.经过反复的尝试和错误,我设法提出了一个解决方案.

Thanks to everyone who answered. After much trial and error, I managed to come up with a fix.

首先,我从HABTM切换为 has_many:through 关系,将联接模型称为 categorization.rb (而不是categorizations_posts.rb)-注意:下面详述的修复程序也可能也适用于HABTM:

First of all, I switched from a HABTM to a has_many :through relationship, calling my join model categorization.rb (instead of categorizations_posts.rb) - NB: the fix detailed below will likely work with a HABTM too:

第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

从上面的帖子模型中可以看出:如果要启用选择多个现有类别的权限,则必须存在名为:category_ids 的访问者,但您不要需要访问器方法来创建新类别...我不知道.

From the post model above: obviously, the accessor named :category_ids must be present if you want to enable selecting multiple existing categories, but you do not need an accessor method for creating new categories... I didn't know that.

第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

From the view code above, it's important to note the use of fields_for :category as opposed to the somewhat unintuitive fields_for :categories_attributes

第3步 最后,我向控制器添加了一些代码:

Step 3 Finally, I added some code to my controller:

# 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

现在,当我创建新帖子时,我可以同时从选择菜单中选择多个现有类别 ,并同时创建一个全新的类别-并非单项或另一个

Now, when I create a new post, I can simultaneously choose multiple existing categories from the select menu and create a brand new category at the same time - it's not a case of one-or-the-other

只有一个小错误会在编辑和更新现有帖子时发生;在这种情况下,它不会让我同时创建一个新类别选择多个现有类别-如果我尝试同时执行这两个类别,则只有现有类别与该帖子相关联,并且全新的被拒绝(无错误消息). 但是我可以通过两次编辑帖子来解决这个问题,一次创建一个新类别(将其与帖子自动关联),然后第二次从菜单中选择一些其他现有类别-例如我说这没什么大不了的,因为否则一切都会非常好,否则我的用户可以适应这些限制

There is one tiny bug which only occurs when editing and updating existing posts; in this case it won't let me simultaneously create a new category and select multiple existing categories - if I try to do both at the same time, then only the existing categories are associated with the post, and the brand-new one is rejected (with no error message). But I can get round this by editing the post twice, once to create the new category (which automagically associates it with the post) and then a second time to select some additional existing categories from the menu - like I said this is not a big deal because it all works really well otherwise and my users can adapt to these limits

无论如何,我希望这对某人有帮助.

Anyway, I hope this helps someone.

阿们.

这篇关于HABTM关系和accepts_nested_attributes_for的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆