在表单中关联(has_one)多个模型

时间:2011-02-10 04:33:37

标签: ruby-on-rails ruby-on-rails-3

在保存数据之前,我无法关联外键(当存储在数据库中时,网络模型的字段'user_id'为空)。我是RoR的新手,所以如果我的代码很草率,请原谅我: - )

型号:

class Network < ActiveRecord::Base
  belongs_to :user
end


class User < ActiveRecord::Base
has_one  :network, :foreign_key => "user_id",
                   :dependent => :destroy

控制器:

class UsersController < ApplicationController
def new
  @user = User.new
  @network = @user.build_network
  @title = "Sign Up"
end

def create
  @user = User.new(params[:user])
  if (@user.save)
    @network = Network.new(params[:network])
    if (@network.save)
      sign_in @user
      flash[:success] = "Welcome!"
      redirect_to @user
    else
      @title = "Sign up"
      render 'new'
    end
  else
    @title = "Sign up"
    render 'new'
  end
end

我能够从视图中获取所有用户输入而不会出现问题(使用form_for和fields_for)。除了使用@ user.build_network?

之外,我还必须明确定义has_one关联吗?

根据使用accepts_nested_attributes_for的建议,我将控制器清理为

def new
  @user = User.new
  @user.build_network
  @title = "Sign Up"
end

def create
  @user = User.new(params[:user])
  if (@user.save)
    sign_in @user
    flash[:success] = "Welcome!"
    redirect_to @user        
  else
    @title = "Sign up"
    render 'new'
  end
end

用户模型中更新的关联:

has_one  :network, :class_name => 'Network',
         :foreign_key => "user_id",
         :dependent => :destroy

accepts_nested_attributes_for :network,
                              :reject_if => :all_blank,
                              :allow_destroy => true

但是,当我提交表单时,network_attributes都是空白的。我已按照提供的链接中的说明以及http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes(以及更多)

我不认为这是视图/表单的问题,因为我可以使用Network.new(params[:network]

访问属性

有任何想法/建议吗?

2 个答案:

答案 0 :(得分:3)

这是使用accepts_nested_attributes_for

的完美情况

查看http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html以及http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for,了解如何使用form_for

轻松实现它

(问题后更新)

如果您可以访问Networkparams[:network]的属性,那么(遗憾的是!)错过了嵌套属性的一个更微妙的部分,即fields_for的调用

我假设你有以下几点(使用HAML语法来提高速度):

= form_for @user do |f|
  = f.text_field :name
  = f.text_field :email_address

  - fields_for @network do |n|
    = n.text_field :name

问题在于,Rails未在UserNetwork字段之间的表单中看到任何明确的连接。 (这很聪明,但不是 智能)

您明确声明Network嵌套在User中的方式(为了更新嵌套属性,请确保在 {{{{{{} {{}}上调用fields_for @network函数1}} 表单构建器,而不是单独构建:

User

这样,当您提交表单并检查= form_for @user do |f| = f.text_field :name = f.text_field :email_address - f.fields_for @network do |n| = n.text_field :name 时,您会注意到您同时拥有paramsparams[:user] - 哪些Rails会识别为嵌套属性并且< em>应该然后保存它们并将它们链接在一起。

答案 1 :(得分:2)

您可能需要将网络设置为attr_accessible,以及User模型的其他属性,如下所示:

attr_accessible :name, :age, :network_attributes, ...

请注意,您还需要在列表中放置您想要的“大量分配”所有属性,例如:上面示例中的name和:age。