如何在 Rails 4中使用 attr_access?

attr_accessible似乎不再工作在我的模型。

在 Rails 4中允许大量分配的方法是什么?

150841 次浏览

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动作控制器指南中的信息。

请注意:如果你仍然想使用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

我们可以用

params.require(:person).permit(:name, :age)

当person是Model时,你可以将此代码传递给方法person_params &在create方法或else方法中代替参数[:person]使用

1)通过在应用程序的Gemfile中添加这一行来更新设计,以便它可以处理Rails 4.0:

gem 'devise', '3.0.0.rc'

然后执行:

$ bundle

2)将attr_accessible的旧功能再次添加到rails 4.0

尝试使用attr_accessible,不要注释掉它。

将这一行添加到应用程序的Gemfile中:

gem 'protected_attributes'

然后执行:

$ bundle

Rails 5的更新:

gem 'protected_attributes'

似乎已经不管用了。但给:

宝石的protected_attributes_continued

一试。

我不得不将Rails应用程序从3.2迁移到6.1,所以即使是gem 'protected_attributes'也不是一个选项。我很欣赏在控制器中使用require().permit()的参数,但我不想从模型中重新键入或剪切和粘贴所有这些属性,所以我决定使用这个初始化器代码(放在config/initializers文件中):

# 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