在同一个字段上使用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模型添加属性,并且仍应检索持久化实例。