2012-06-18 72 views
0

我有一个小示例应用程序,有3个模型:成员,组和订阅。这个想法是,成员可以订阅组。嵌套窗体和has_many:通过

ERD

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

回答

0

多小时的排查和挫折后,我把它报告给开发者的Rails,我终于有了一个解决方案:

的Rails 3无法初始化GROUP_ID和member_id自动的方式,在这个问题定义。

所以,就目前而言,有两种方法,使其工作:

  1. 添加member_id为在视图中隐藏字段。
  2. 改变一切,所以订阅模型谁拥有accepts_nested_attributes_for。这样,要创建的新对象就是Subscription,而Group就是嵌套模型。

第一个选项有一个重要的安全漏洞,所以我不推荐它。

第二个选项虽然没有太多逻辑,但更清洁,应该是解决这个问题的“Rails方法”。

0

确保所有你想分配属性attr_accessible。您可以禁用它并查看它是否有效,或者查看Rails服务器日志中的警告。

更新:您应该将colleg_nested_attributes_for添加到成员模型,并使用带有fields_for的多模型表单。

+0

是的,它们都可以访问。你可以在我发布的问题模型中看到它们。 –

+0

您是否在创建操作中遇到错误?它是否可以从控制台上运行? –

+0

是的,错误在创建操作中。在这里,你有我正在试图做到这一点:https://github.com/idavemm/nested_form/blob/master/app/controllers/groups_controller.rb –

0

我认为你在错误地思考你的模型。每个成员是否会为每个组别介绍不同的介绍。那么,例如,member1会有一个介绍,而member2有不同的介绍?

订阅模型应该存储关于成员和组之间关系的信息。在这种情况下,引入组合模型会更好。 您收到错误的原因是因为您正尝试为尚未创建的组创建订阅(当您设置介绍属性时)。

因此,将介绍移到组模型中,然后如果您希望组的创建者自动订阅(您应该),请添加代码以在create action中为控制器创建订阅记录保存后。然后,在订阅模型中,您可以做一些很酷的事情,比如让一个状态机跟踪该组的成员状态(主持人,新手,老成员等)。

+0

不!每个订阅都有一个介绍。每个成员都会为每个组进行介绍。这是一个典型的has_many:通过关系。介绍不能转移到组,因为它代表不同的事情。 –

+0

我明白了。那么谁来设置介绍?例如,创建一个组,然后几天后一个成员订阅该组,那么将如何为该新成员设置介绍。 – GorrillaMcD

+0

这可以用另一种形式来完成(实际上,这部分是我已经编程和运行良好的部分)。引言是插入表单中的嵌套属性,请看看我链接的代码(github),你会看到它的工作原理。 –

0

我只是碰到了同样的问题,解决办法是删除相关的模型(基于this question)的存在验证,在你的情况下,删除:

验证:GROUP_ID,存在:真

一旦验证失效,一切都像发条一样运行

相关问题