在同一字段上使用 attr_accessor 和 attr_accessible

发布于 2024-10-12 18:25:17 字数 171 浏览 8 评论 0原文

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

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end

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

What happens in the background with the following code?

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end

Hint: When instantiating the class, will it be persisted to the database? Why or why not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

埋葬我深情 2024-10-19 18:25:17

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

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

attr_accessor is ruby code and is used when you do not have a column in your database, but still want to show a field in your forms. The only way to allow this is to attr_accessor :fieldname and you can use this field in your View, or model, if you wanted, but mostly in your View.

attr_accessible allows you to list all the columns you want to allow Mass Assignment, as andy eluded to above. The opposite of this is attr_protected which means this field i do NOT want anyone to be allowed to Mass Assign to. More then likely it is going to be a field in your database that you don't want anyone monkeying around with. Like a status field, or the like.

一身软味 2024-10-19 18:25:17

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

attr_accessible 仅允许通过批量分配(例如,使用update_attributes)来分配字段。这对于安全目的很有好处。更多信息请参阅 MassAssignmentSecurity API 文档

In most cases, you don't need to use attr_accessor if the field is a column in the users table in your database. ActiveRecord will figure it out for you.

attr_accessible simply allows to field to be assigned via mass assignment (e.g., with update_attributes). This is good for security purposes. More information from the MassAssignmentSecurity API docs.

染墨丶若流云 2024-10-19 18:25:17

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

(在一个相关的问题中,我收到了很多 nil 错误,例如“对象不支持 #inspect”和“nil:NilClass 的未定义方法'keys'”。我现在通过删除 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 描述了数据库中应该可以从外部访问的字段,但在这种情况下似乎没有什么区别。

Thanks everyone for quick answers!
Your answers combined gave me the pieces I needed to understand this puzzle, I think.

(In a related problem, I was getting a lot of nil errors like "Object doesn’t support #inspect", and "undefined method ‘keys’ for nil:NilClass". I managed to solve it now, by removing the att_accessor field altogether.)

By experimenting with this particular case, this is what I've found out:

Actually, the :name field won't be persisted to the database.

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

Will only set the attribute on the object, but not persist the :name column to the database. Like the following 'rails console' output shows:

> 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>

I assume this is because *the setter made by attr_accessor will override ActiveRecord's setter* (which takes care of the database persistence). You can still retrieve the value from the :name field from the object though, like this:

> user.name
=> "somename"

So, in conclusion, I've learnt that using attr_accessor on fields might lead to them not being persisted to the database. And while I thought attr_accessible describes fields in the database that should be accessible from the outside, it doesn't seem to make a difference in this case.

少女的英雄梦 2024-10-19 18:25:17

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

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

Since it inherits ActiveRecord, it will be persisted when you call the save method (but not when it is instantiated).

If you don't have any attributes for that model, I assume ActiveRecord will simply save a new row in the database (i.e. your object will only have a persisted id). This makes sense, as you might later add attributes to your User model, and the persisted instances should still be retrievable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文