嵌套受保护模型的“无法批量分配受保护属性”
Posted
技术标签:
【中文标题】嵌套受保护模型的“无法批量分配受保护属性”【英文标题】:"Can't mass-assign protected attributes" with nested protected models 【发布时间】:2012-09-05 00:51:29 【问题描述】:我正在努力让这个嵌套模型工作。我已经尝试了各种复数/单数形式,完全删除了 attr_accessible,谁知道还有什么。
餐厅.rb:
# == RESTAURANT MODEL
#
# Table name: restaurants
#
# id :integer not null, primary key
# name :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class Restaurant < ActiveRecord::Base
attr_accessible :name, :job_attributes
has_many :jobs
has_many :users, :through => :jobs
has_many :positions
accepts_nested_attributes_for :jobs, :allow_destroy => true
validates :name, presence: true
end
job.rb:
# == JOB MODEL
#
# Table name: jobs
#
# id :integer not null, primary key
# restaurant_id :integer
# shortname :string(255)
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class Job < ActiveRecord::Base
attr_accessible :restaurant_id, :shortname, :user_id
belongs_to :user
belongs_to :restaurant
has_many :shifts
validates :name, presence: false
end
restaurants_controller.rb:
class RestaurantsController < ApplicationController
before_filter :logged_in, only: [:new_restaurant]
def new
@restaurant = Restaurant.new
@user = current_user
end
def create
@restaurant = Restaurant.new(params[:restaurant])
if @restaurant.save
flash[:success] = "Restaurant created."
redirect_to welcome_path
end
end
end
new.html.erb:
<% provide(:title, 'Restaurant') %>
<%= form_for @restaurant do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label "Restaurant Name" %>
<%= f.text_field :name %>
<%= f.fields_for :job do |child_f| %>
<%= child_f.label "Nickname" %>
<%= child_f.text_field :shortname %>
<% end %>
<%= f.submit "Done", class: "btn btn-large btn-primary" %>
<% end %>
输出参数:
"utf8"=>"✓",
"authenticity_token"=>"DjYvwkJeUhO06ds7bqshHsctS1M/Dth08rLlP2yQ7O0=",
"restaurant"=>"name"=>"The Pink Door",
"job"=>"shortname"=>"PD",
"commit"=>"Done"
我收到的错误是:
ActiveModel::MassAssignmentSecurity::Error in RestaurantsController#create
Cant mass-assign protected attributes: job
Rails.root: /home/johnnyfive/Dropbox/Projects/sa
Application Trace | Framework Trace | Full Trace
app/controllers/restaurants_controller.rb:11:in `new'
app/controllers/restaurants_controller.rb:11:in `create'
任何人都有 ANY 线索如何让它工作?谢谢!
【问题讨论】:
与您的问题无关 - 我注意到每个类顶部的 cmets 定义了数据库结构。保持更新是一件很痛苦的事,而且很容易变得陈旧。 Rails 在运行迁移时自动更新 schema.rb 做得很好,并且可能是您根据模型记录数据库的更好方法。 @MichaelShimmins 我不这样做,它是由 gem 'annotate' 完成的。 【参考方案1】:在餐厅.rb:
应该是
attr_accessible :name, :jobs_attributes
代替
attr_accessible :name, :job_attributes
【讨论】:
谢谢你(不太确定),但是我在当前的迭代中有这个,我仍然收到同样的错误。 餐厅模特有很多工作,所以我想你应该把<%= f.fields_for :jobs do |child_f| %>
而不是:job
@Kishie,我同意你的观点,并且也尝试过,但是当我这样做时,在浏览器中查看时,“短名称”字段会完全消失。我敢肯定这很简单,但我这辈子都想不通。
@JohnnyFive @kishie 所说的一切都是正确的。我认为您的问题是没有将任何工作记录添加到您的 @restraunt
对象的结果。如果您遵循@kishie 的建议并将3.times @restaurant.jobs.build
添加到RestaurantsController#new
操作的末尾会发生什么。
@JohnnyFive 这是因为f.fields_for
试图遍历与@restaurant
对象关联的所有作业。但是,因为@restaurant
是一个新对象,您需要手动添加一些默认作业。有关嵌套表单如何工作的更多信息,请观看 railscasts.com/episodes/196-nested-model-form-part-1 上的视频,这是我学习如何使用嵌套表单的地方。【参考方案2】:
关于您的最后评论: 您可以在工作表中提交 user_id,这应该将 user_id 提交给模型
【讨论】:
以上是关于嵌套受保护模型的“无法批量分配受保护属性”的主要内容,如果未能解决你的问题,请参考以下文章
在 Laravel 中创建模型时使用受保护的 $table 变量