在同一个字段上使用attr_accessor和attr_accessible

Mag*_*gne 21 field ruby-on-rails attr-accessor attr-accessible

使用以下代码在后台会发生什么?

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end
Run Code Online (Sandbox Code Playgroud)

提示:实例化类时,是否会持久化到数据库?为什么或者为什么不?

pja*_*mer 70

attr_accessor是ruby代码,当您在数据库中没有列但仍希望在表单中显示字段时使用.允许此操作的唯一方法是attr_accessor :fieldname,您可以在视图或模型中使用此字段(如果需要),但主要在视图中.

attr_accessible允许您列出要允许批量分配的所有列,如上所述.与此相反的是attr_protected,这意味着这个字段我不希望任何人被允许进行质量分配.更有可能的是,你不希望任何人在你的数据库中使用这个字段.像状态字段等.


And*_*man 5

在大多数情况下,attr_accessor如果字段是users数据库中表的列,则无需使用.ActiveRecord会为你解决这个问题.

attr_accessible只允许通过质量分配(例如,用update_attributes)分配字段.这有利于安全目的.来自MassAssignmentSecurity API文档的更多信息.


Mag*_*gne 4

感谢大家的快速解答!\n我认为,您的答案综合起来为我提供了理解这个难题所需的部分。

\n\n

(在一个相关的问题中,我收到了很多零错误,例如“对象不\ xe2 \ x80 \ x99t支持#inspect”和“未定义方法\ xe2 \ x80 \ x98keys \ xe2 \ x80 \ x99 for nil:NilClass” .我现在成功解决了这个问题,通过完全删除 att_accessor 字段。)

\n\n

通过对这个特殊情况进行实验,我发现:

\n\n

实际上,:name 字段不会被持久化到数据库中。

\n\n
user = User.new(:name=>"somename")\n
Run Code Online (Sandbox Code Playgroud)\n\n

只会在对象上设置属性,但不会将 :name 列保留到数据库中。就像下面的“rails console”输出所示:

\n\n
> user\n=> <User id: nil, created_at: nil, updated_at: nil>\n> user.save\n=> true\n> user\n=> <User id:1, created_at: 2011-01-19 12:37:21, updated_at: 2011-01-19 12:37:21>\n
Run Code Online (Sandbox Code Playgroud)\n\n

我认为这是因为 *attr_accessor 制作的 setter 将覆盖 ActiveRecord\ 的 setter* (负责数据库持久性)。不过,您仍然可以从对象的 :name 字段中检索值,如下所示:

\n\n
> user.name\n=> "somename"\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,总而言之,我了解到在字段上使用 attr_accessor 可能会导致它们无法持久保存到数据库中。虽然我认为 attr_accessible 描述了数据库中应该可以从外部访问的字段,但在这种情况下似乎没有什么区别。

\n