21

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

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end

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

4

4 回答 4

70

attr_accessor 是 ruby​​ 代码,当您的数据库中没有列但仍想在表单中显示字段时使用。允许这样做的唯一方法是attr_accessor :fieldname,如果需要,您可以在视图或模型中使用此字段,但主要是在视图中。

attr_accessible 允许您列出您想要允许批量分配的所有列,正如 andy 上面所忽略的那样。与此相反的是 attr_protected,这意味着我不希望允许任何人批量分配到该字段。更有可能的是,它会成为您的数据库中的一个字段,您不希望任何人与之胡闹。像状态字段等。

于 2011-01-15T18:22:35.710 回答
5

在大多数情况下,如果字段是数据库表中attr_accessor的列,则不需要使用。usersActiveRecord 将为您解决。

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

于 2011-01-15T17:21:17.863 回答
4

感谢大家的快速解答!我想,你的答案加起来给了我理解这个谜题所需的部分。

(在一个相关问题中,我遇到了很多 nil 错误,例如“对象不支持#inspect”和“nil:NilClass 的未定义方法'键'”。我现在设法通过删除 att_accessor 字段来解决它共。)

通过试验这种特殊情况,这就是我发现的:

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

user = User.new(:name=>"somename")

只会在对象上设置属性,但不会将 :name 列持久化到数据库中。就像下面的“rails 控制台”输出所示:

> 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 描述了应该从外部访问的数据库中的字段,但在这种情况下似乎没有什么不同。

于 2011-01-19T13:22:44.310 回答
1

由于它继承,因此在您调用方法时(但在实例化时不会)ActiveRecord,它将被持久化。save

如果您没有该模型的任何属性,我假设ActiveRecord只会在数据库中保存一个新行(即您的对象将只有一个 persisted id)。这是有道理的,因为您以后可能会向User模型添加属性,并且持久化的实例应该仍然可以检索。

于 2011-01-15T16:49:23.720 回答