为什么attr_accessor会破坏Ruby on Rails中此模型中的现有变量? [英] Why does attr_accessor clobber the existing variables in this model in Ruby on Rails?

查看:65
本文介绍了为什么attr_accessor会破坏Ruby on Rails中此模型中的现有变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近对此很痛苦,准确地知道是什么使这种情况发生是有用的,所以其他人可以避免这个错误.

I was bitten by this recently, and it'd be useful to know precisely what's happening to make this happen, so others avoid this mistake.

我有一个模型用户,其架构如下:

I have a model User, with a schema like so:

create_table "users", :force => true do |t|
    t.string   "user_name"
    t.string   "first_name"
    t.string   "last_name"
    t.string   "email"
    t.string   "location"
    t.string   "town"
    t.string   "country"
    t.string   "postcode"
    t.boolean  "newsletter"

在user.rb类中,我有一个用于三种方法的attr_accessor:

In the class user.rb, I have a attr_accessor for three methods:

class User < ActiveRecord::Base

# lots of code

  attr_protected :admin, :active

# relevant accessor methods

  attr_accessor :town, :postcode, :country 

end

现在,在我的用户控制器中,如果我具有以下方法:

Now in my user controller, if I have the following method:

def create
    @user = User.new params[:user]
end

当我尝试使用此params哈希中的内容创建新用户时:

When when I try to create a new user with the contents in this params hash:

  --- !map:HashWithIndifferentAccess 
  # other values
  country: United Kingdom
  dob(1i): "1985"
  dob(2i): "9"
  dob(3i): "19"
  town: london

返回的对象具有countrytown和邮政编码postcode值的空字符串,就像这样.

The returned object has empty strings for the country, town and postcode postcode values, like so.

(rdb:53) y user1
--- !ruby/object:User 
attributes: 
  # lots of attributes that aren't relevant for this example, and are filled in okay
  postcode: 
  country: 
  town: 

我可以说attr_accessor方法正在破坏Active Record的现有访问器方法,因为当我将它们全部取出时,它们都可以正常工作,因此解决方案非常简单-只需将它们取出即可.

I can tell that the attr_accessor methods are clobbering Active Record's existing accessor methods, because when I take them out all works fine, so the solution is fairly straightforward - just take them out.

但是什么在这里发生了什么呢?

But what exactly is happening when here?

我在这里用于Active Record的Rails API文档,以及此处的

I'm looking here in the Rails API docs for Active Record, and here in Ruby's own docs about attr_accessor, but I'm still slightly hazy about how attr_accessor is breaking things here.

有什么办法可以阻止其他可怜的灵魂对此犯规呢?

Any able to shed some light to stop some other poor soul falling foul of this?

推荐答案

当您将attr_accessor添加到一个类时,它会在其上定义两个方法,例如User#postcode和User#postcode =.

When you add an attr_accessor to a class, it defines two methods on it, e.g. User#postcode and User#postcode=.

如果访问器的名称等于模型属性的名称,则事情会中断(如果您不小心的话).当您为模型分配属性时,将调用User#postcode =,在您的情况下,它只会执行任何操作

If the name of the accessor is equal to a name of a model attribute, things break (if you're not careful). When you assign attributes to the model, User#postcode= is called and in your case it does nothing except

@postcode = value

因此,该值仅存储在实例变量中,而不会出现在属性哈希中.

So the value just gets stored in an instance variable and doesn't appear in the attributes hash.

在正常情况下(没有访问器),这将转到method_missing并最终触发类似

Whereas in a normal scenario (without an accessor) this would go to method_missing and eventually trigger something like

write_attribute(:postcode, value)

然后它将出现在模型的属性中. 希望有道理.

And then it would appear in your model's attributes. Hope that makes sense.

这篇关于为什么attr_accessor会破坏Ruby on Rails中此模型中的现有变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆