使用以下代码在后台会发生什么?
class User < ActiveRecord::Base
attr_accessor :name
attr_accessible :name
end
提示:实例化类时,是否会持久化到数据库?为什么或为什么不呢?
答案 0 :(得分:70)
attr_accessor是ruby代码,在数据库中没有列但仍希望在表单中显示字段时使用。允许此操作的唯一方法是attr_accessor :fieldname
,如果您愿意,可以在视图或模型中使用此字段,但主要在您的视图中。
attr_accessible允许您列出要允许批量分配的所有列,如上所述。与此相反的是attr_protected,这意味着这个字段我不希望任何人被允许进行质量分配。更有可能的是,你不希望任何人围绕着你的数据库中的一个字段。像状态字段一样。
答案 1 :(得分:5)
在大多数情况下,如果字段是数据库中attr_accessor
表中的列,则不需要使用users
。 ActiveRecord会为你解决这个问题。
attr_accessible
只允许通过质量分配来指定字段(例如,使用update_attributes
)。这有利于安全目的。来自MassAssignmentSecurity API docs的更多信息。
答案 2 :(得分:4)
感谢大家快速解答! 你的答案结合起来给了我理解这个难题所需的部分,我想。
(在一个相关的问题中,我得到了很多nil错误,例如“Object不支持#inspect”,以及nil的“undefined方法'键':NilClass”。我设法现在通过删除完全是att_accessor字段。)
通过试验这个特例,这就是我发现的:
实际上,:name字段不会持久保存到数据库中。
user = User.new(:name=>"somename")
只会在对象上设置属性,但不会将:name列保存到数据库中。像下面的'rails console'输出显示:
> user
=> <User id: nil, created_at: nil, updated_at: nil>
> user.save
=> true
> user
=> <User id:1, created_at: 2011-01-19 12:37:21, updated_at: 2011-01-19 12:37:21>
我认为这是因为* attr_accessor创建的setter将覆盖ActiveRecord的setter *(它负责数据库持久性)。您仍然可以从对象的:name字段中检索值,如下所示:
> user.name
=> "somename"
因此,总而言之,我已经了解到在字段上使用attr_accessor可能会导致它们不会持久存储到数据库中。虽然我认为attr_accessible描述了数据库中应该可以从外部访问的字段,但在这种情况下似乎没有什么区别。
答案 3 :(得分:1)
由于它继承了ActiveRecord
,因此在调用save
方法时会保留它(但在实例化时不会保留)。
如果你没有该模型的任何属性,我认为ActiveRecord
只会在数据库中保存一个新行(即你的对象只有一个持久的id
)。这是有道理的,因为您稍后可能会向User
模型添加属性,并且仍应检索持久化实例。