2015-12-18 91 views
2

我有一个Rails模型叫做Biography,传记有一种生活方式。为什么这个rails嵌套属性分配不起作用

class Lifestyle < ActiveRecord::Base 
    belongs_to :biography 
end 

class Biography < ActiveRecord::Base 
    has_one :lifestyle, dependent: :destroy 
    accepts_nested_attributes_for :lifestyle 
end 

,在我BiographyController我有这样的:

def update_biography 
    biography = current_user.biography 
    logger.debug("params are: #{params}") 
    logger.debug("biography_params are: #{biography_params}") 
    if biography.update(biography_params) 
    render :json => biography 
    else 
    render :json => { :errors => biography.errors.full_messages }, :status => 400 
    end 
end 

def biography_params 
      params.require(:biography).permit(
             :disability, :hiv_positive, :blood_type, 
             lifestyle_attributes: [:id, :diet, :smoke, :drink]) 
end 

这是我从上面我的两个logger.debug语句得到:

params are: {"lifestyle_attributes"=>{"diet"=>"2", "smoke"=>"false", "drink"=>"2"}, "disability"=>"false", "hiv_positive"=>"false", "blood_type"=>"3", "controller"=>"biographies", "action"=>"update_biography", "id"=>"4", "biography"=>{"disability"=>"false", "hiv_positive"=>"false", "blood_type"=>"3"}} 

biography_params are: {"disability"=>"false", "hiv_positive"=>"false", "blood_type"=>"3"} 

这是为什么我biography_params尽管我已在传记模型中使用了accepted_nested_attributes_for statment,并且还定义了模型中传记与生活方式之间的关联,但不包含lifestyle_attributes?我还在强大的参数许可列表中添加了lifestyle_attributes。

但是,如果我在轨运行这个控制台分配不工作:

b = Biography.first 
b.update("lifestyle_attributes"=>{"diet"=>"2", "smoke"=>"false", "drink"=>"2"}) 
+2

你的参数应该是'params = {“biography”=> {“first_name”=>“new”,“last_name”=>“user”,“lifestyle_attributes”=> {“diet”=>“2” “smoke”=>“false”,“drink”=>“2”}}' –

+0

张贴您的表格为 –

+0

我没有表格。我正在使用backbone.js视图并发送json请求。这是标题:blood_type:“3” 残疾:“false” hiv_positive:“false” lifestyle_attributes:{diet:“2”,smoke:“false”,drink:“2”} – user1801879

回答

1

您可以尝试

params = {biography: {first_name: "new", last_name: "user", disability: false, hiv_positive: false, blood_type: 3, "lifestyle_attributes: {diet: "2", smoke: "false", drink: "2"}} 

如果你不希望你的PARAMS biography:你可以在params.require(:biography)忽略require(:biography)到只params.permit(...)

现在希望它能工作

你获得更多的信息上Nested Attributes

+0

谢谢,我今天就试一试。 – user1801879

+0

deleing require语句做了伎俩。删除需要危险吗?在那里有什么好处?此外,它还为每次更新创建新的生活方式标识。 – user1801879

+0

“转到每个控制器的操作通过参数在该模型上通过参数触发批量分配”,在此模型中,以便您了解哪种型号...您忽略要求意味着型号不是关注只是允许 –

2

requirepermit实际上的ActionController::Parameters的方法。 require在这种情况下是:biography需要出现在您从骨干视图发送的散列中。

require方法确保特定参数存在,并且如果不是,只要它,则需要方法引发错误。它返回ActionController::Parameters的实例,以便传递给要求的密钥,例如:biography

+0

您所说的话是有道理的。但是,如果我从许可证中删除lifestyle_attributes,为什么一切正常。如果您看到“params are:”的记录器语句,则在它的末尾有“:biography =>”,即使我没有将它发送到从骨干视图生成的哈希中。 – user1801879

1

的问题是,lifestyle_attributes不是biography PARAMS散列的一部分。您应该有:

params: { 
    biography: { 
     lifestyle_attributes: { 
     ... 
     } 
    } 
} 

这将使PARAMS方法正确地访问数据。

要解释它是如何工作的,你需要看看ActionController::Parameters类是如何工作的:

返回一个新ActionController::Parameters实例只包含给定的过滤器,并设置为对象,以真实的允许属性。

每次使用params.require(:x).permit(:y)时,它会返回一个新的哈希与允许PARAMS。这些允许的参数必须嵌套在所需的参数之内。

正如您已经证明的那样,这个效果很好......

biography_params是:{"disability"=>"false", "hiv_positive"=>"false", "blood_type"=>"3"}

的问题是,由于lifestyle_attributes嵌套biography下,它的参数不调用PARAMS方法后返回。


对此问题进行修复将是你的形式

#app/views/biographies/new.html.erb 
<%= form_for @biography do |f| %> 
    <%= ... biography attributes %> 
    <%= f.fields_for :lifestyle do |l| %> 
     <%= lifestyle fields %> 
    <% end %> 
    <%= f.submit %> 
<% end %> 

我不知道该怎么你现在做到了,但不知何故,你已经连接之外lifestyle属性biography散列。

相关问题