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