attr_accessible
似乎不再适用于我的模型。
在 Rails 4 中允许批量分配的方法是什么?
Rails 4 现在使用强参数。
保护属性现在在控制器中完成。这是一个例子:
class PeopleController < ApplicationController
def create
Person.create(person_params)
end
private
def person_params
params.require(:person).permit(:name, :age)
end
end
不再需要attr_accessible
在模型中设置。
accepts_nested_attributes_for
为了使用accepts_nested_attribute_for
强参数,您需要指定应将哪些嵌套属性列入白名单。
class Person
has_many :pets
accepts_nested_attributes_for :pets
end
class PeopleController < ApplicationController
def create
Person.create(person_params)
end
# ...
private
def person_params
params.require(:person).permit(:name, :age, pets_attributes: [:name, :category])
end
end
关键字是不言自明的,但以防万一,您可以在 Rails Action Controller 指南中找到有关强参数的更多信息。
注意:如果你还想使用attr_accessible
,你需要添加protected_attributes
到你的Gemfile
. 否则,您将面临RuntimeError
.
如果你更喜欢 attr_accessible,你也可以在 Rails 4 中使用它。你应该像 gem 一样安装它:
gem 'protected_attributes'
之后,您可以像在 Rails 3 中一样在模型中使用 attr_accessible
另外,我认为这是最好的方法——使用表单对象来处理批量赋值,保存嵌套对象,你也可以这样使用 protected_attributes gem
class NestedForm
include ActiveModel::MassAssignmentSecurity
attr_accessible :name,
:telephone, as: :create_params
def create_objects(params)
SomeModel.new(sanitized_params(params, :create_params))
end
end
Rails 5 的更新:
gem 'protected_attributes'
似乎不再起作用了。但是给:
宝石'protected_attributes_continued'
试一试。
我们可以用
params.require(:person).permit(:name, :age)
其中 person 是模型,您可以在方法 person_params 上传递此代码并在 create 方法或 else 方法中代替 params[:person] 使用
1) 更新 Devise 以便它可以处理 Rails 4.0,方法是将此行添加到应用程序的 Gemfile:
gem 'devise', '3.0.0.rc'
然后执行:
$ bundle
attr_accessible
2)在rails 4.0中再次添加旧功能
尝试使用attr_accessible
,不要注释掉。
将此行添加到应用程序的 Gemfile:
gem 'protected_attributes'
然后执行:
$ bundle
我不得不将 Rails 应用程序从 3.2 迁移到 6.1,所以即使 gem 'protected_attributes' 也不是一个选择。我很欣赏在控制器中使用 require().permit() 的参数,但我不想从模型中重新键入或剪切和粘贴所有这些属性,所以我决定改用这个初始化代码(放在一个文件中)在配置/初始化程序中):
# fix attr_accessible in an initializer
# wrap ActionController::Parameters code in singleton method defined
# from attr_accessible so controller code can call class method
# to get permitted parameter list
# e.g. model: class A < ActiveRecord::Base,
# controller calls A.permit_attr(params)
# lots simpler than moving all attr_accessible definitions to controllers
# bug: fails if more than one attr_accessible statement
def (ActiveRecord::Base).attr_accessible *fields
puts "attr_accessible:"+self.name+":permitted_params fields=#{fields.inspect}"
define_singleton_method("permit_attr") { |params|
# may have subclasses where attr_accessible is in superclass
# thus must require by subclass name so should calculate require at runtime
rq = self.name.downcase.to_sym
puts "...permit_attr:self=#{rq} permit(#{fields.inspect})"
params.require(rq).permit(fields)
}
end
为了防止出现多个 attr_accessible 声明,在定义方法之前,添加
raise "error: model can only have one attr_accessible declaration" if defined? permit_attr