“警告:不能批量分配受保护的属性”

我使用RESTful技术来生成一个模型(实际上,我正在使用Devise gem,这对我来说是这样做的),并且我在模型中添加了名为first_name和last_name的新字段。 移民进展良好。 我在模型中添加了attr_accessor:first_name,:last_name,并预计它会工作。 但是当我尝试用Doctor.create({:first_name =>“MyName”})等等批量分配新的实例时,我收到错误,说我不能批量分配受保护的属性。

我认为使用attr_accessor的重点是解决模型字段的保护问题。 你能帮我理解这个信息吗?

编辑:哦,顺便说一句,logging也不会创build。 我以为他们应该是因为这只是一个警告,但他们不在数据库上。

编辑2:这是我的模型

class Doctor < User has_many :patients has_many :prescriptions, :through=> :patients validates_presence_of :invitations, :on => :create, :message => "can't be blank" attr_accessor :invitations end 

和架构,它没有first_name和last_name,因为它们是在医生的祖先users表中创build的。 我用单表inheritance。

 create_table :doctors do |t| t.integer :invitations t.timestamps end 

这是迁移到更改用户表

 add_column :users, :first_name, :string add_column :users, :last_name, :string add_column :users, :type, :string 

编辑:这里是种子文件。 我不包括truncate_db_table方法,但它的工作原理。

 %w{doctors patients}.each do |m| truncate_db_table(m) end Doctor.create(:invitations=>5, :email=>"email@gmail.com", :first_name=>"Name", :last_name=>"LastName") Patient.create(:doctor_id=>1, :gender=>"male", :date_of_birth=>"1991-02-24") 

不要将attr_accessorattr_accessible混淆。 Accessor被内置到Ruby中,并且定义了一个getter方法 – model_instance.foo # returns something – 和一个setter方法 – model_instance.foo = 'bar'

可访问性由Rails定义,并使该属性成为可分配的(与attr_protected相反)。

如果first_name是模型数据库表中的字段,那么Rails已经为该属性定义了getter和setter。 所有你需要做的就是添加attr_accessible :first_name

以不安全的方式一起破解你的应用程序完全不适合生产模式:

转到/config/application.rb向下滚动到您将find的地方

 {config.active_record.whitelist_attributes = true} 

将其设置为false。

编辑/顺便说一句(经过4个月的ruby密集的工作,包括一个为期11周的研讨会):DHH认为, 对于noobies (他的话),“跑起来”比“非常安全”更重要。

被build议:虽然这个答案(我认为是第一个在stackoverflow上)现在是+6,它的历史已经低至-4,这意味着很多有经验的rails开发人员感到非常热衷于想要你这样做。

更新:3年后,另一种方法来做到这一点 – 再次,不安全,但比上述解决scheme更好,可能是因为你必须为每个模型

 class ModelName < ActiveRecord::Base column_names.each do |col| attr_accessible col.to_sym end ... end 

这里不要使用attr_accessor。 ActiveRecord在模型上自动创build它们。 另外,如果引发validation或批量分配错误,ActiveRecord将不会创buildlogging。

编辑:你不需要一个医生表,你需要一个用户表与types列来处理Rails 单表inheritance 。 邀请将在用户表上。 嗯,我看到在你添加的代码示例中,你确实input了用户名。 摆脱医生桌,把邀请移交给用户,我想你应该没问题。 也摆脱了attr_accessor。 不需要。

请记住,导轨STI为特定模型的所有类和子类使用相同的表。 您的所有医生logging将在用户表中的一行“医生”

编辑:另外,你确定你只想validation创build的邀请存在,而不是更新?

attr_accessible : variable1, variable2添加到您的表格path文件中。

同意@Robert Speicher的答案但我会强烈build议你应该使用Strong参数而不是attr_accessible来防止质量分配。

干杯!