嵌套窗体和has_many:通过
我有一个小示例应用程序,有3个模型:成员,组和订阅。这个想法是,成员可以订阅组。嵌套窗体和has_many:通过
class Member < ActiveRecord::Base
has_many :subscriptions, dependent: :delete_all
has_many :groups, through: :subscriptions
attr_accessible :email
validates :email, presence: true
end
class Group < ActiveRecord::Base
has_many :subscriptions, dependent: :delete_all
has_many :members, through: :subscriptions
accepts_nested_attributes_for :subscriptions
attr_accessible :name, :subscriptions_attributes
validates :name, presence: true, uniqueness: true
end
class Subscription < ActiveRecord::Base
belongs_to :group
belongs_to :member
attr_accessible :group_id, :introduction
validates :group_id, presence: true
validates :introduction, presence: true
end
我试图创建新组形式,并嵌套introduction
属性中。
我的控制器方法:
def new
@group = Group.new
@group.subscriptions.build
end
def create
@member = Member.first
@group = @member.groups.build(params[:group])
if @group.save
flash[:success] = "Saved"
redirect_to group_path(@group)
else
render :new
end
end
但它不工作。它会抛出错误group_id can't be blank
。所以我不知道如何将新组分配给订阅。
另外,member_id被创建为nil。但正如你所看到的,我从@member
变量创建组,所以我认为它应该被初始化,但它不是。
任何人都可以给我看光?
你可以看到这里的示例应用程序:https://github.com/idavemm/nested_form
多小时的排查和挫折后,我把它报告给开发者的Rails,我终于有了一个解决方案:
的Rails 3无法初始化GROUP_ID和member_id自动的方式,在这个问题定义。
所以,就目前而言,有两种方法,使其工作:
- 添加member_id为在视图中隐藏字段。
- 改变一切,所以订阅模型谁拥有
accepts_nested_attributes_for
。这样,要创建的新对象就是Subscription,而Group就是嵌套模型。
第一个选项有一个重要的安全漏洞,所以我不推荐它。
第二个选项虽然没有太多逻辑,但更清洁,应该是解决这个问题的“Rails方法”。
确保所有你想分配属性attr_accessible。您可以禁用它并查看它是否有效,或者查看Rails服务器日志中的警告。
更新:您应该将colleg_nested_attributes_for添加到成员模型,并使用带有fields_for的多模型表单。
我认为你在错误地思考你的模型。每个成员是否会为每个组别介绍不同的介绍。那么,例如,member1会有一个介绍,而member2有不同的介绍?
订阅模型应该存储关于成员和组之间关系的信息。在这种情况下,引入组合模型会更好。 您收到错误的原因是因为您正尝试为尚未创建的组创建订阅(当您设置介绍属性时)。
因此,将介绍移到组模型中,然后如果您希望组的创建者自动订阅(您应该),请添加代码以在create action中为控制器创建订阅记录保存后。然后,在订阅模型中,您可以做一些很酷的事情,比如让一个状态机跟踪该组的成员状态(主持人,新手,老成员等)。
不!每个订阅都有一个介绍。每个成员都会为每个组进行介绍。这是一个典型的has_many:通过关系。介绍不能转移到组,因为它代表不同的事情。 –
我明白了。那么谁来设置介绍?例如,创建一个组,然后几天后一个成员订阅该组,那么将如何为该新成员设置介绍。 – GorrillaMcD
这可以用另一种形式来完成(实际上,这部分是我已经编程和运行良好的部分)。引言是插入表单中的嵌套属性,请看看我链接的代码(github),你会看到它的工作原理。 –
是的,它们都可以访问。你可以在我发布的问题模型中看到它们。 –
您是否在创建操作中遇到错误?它是否可以从控制台上运行? –
是的,错误在创建操作中。在这里,你有我正在试图做到这一点:https://github.com/idavemm/nested_form/blob/master/app/controllers/groups_controller.rb –