为什么我不能在Active Record回调中直接访问实例变量? [英] Why can't I directly access instance variables in Active Record callback?

查看:101
本文介绍了为什么我不能在Active Record回调中直接访问实例变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Active Record回调中,我总是使用 self来查看示例 .variable 。有时,不需要 self。前缀,因此它们仅使用变量(请参阅此相关问题)。

In Active Record callbacks, I always see examples using self.variable. Sometimes, the self. prefix isn't needed, so they use just variable (see this related question).

根据我的阅读,引用类实例变量的这两种方法都使用了accessor函数,而 @variable 将直接访问变量。在我的代码中,我尝试使用 @variable ,但它不起作用-好像 @variable 还没有定义...您不能直接在Active Record回调中访问实例变量吗?

From what I've read, these two methods of referencing the class instance variable are using the accessor function, whereas @variable would directly access the variable. In my code, I tried to use @variable and it didn't work - it was as if @variable was not defined yet... can you not access instance variables directly in an Active Record callback?

此外,我还没有为此特定变量定义访问器函数,因此当我说 self.variable variable 时实际发生了什么(我已经尝试过这两种方法,并且除了作业的LHS)?

Also, I haven't defined an accessor function for this particular variable, so what actually happens when I say self.variable or variable (I've tried both, and both work aside from the LHS of an assignment)?

是我要问的问题,但我不明白答案,需要进一步澄清(我无法评论这个答案,因为我是新来的。堆栈溢出)。他的答案是这样的:

This question is essentially what I am asking, but I don't understand the answer and want more clarification (I can't comment on the answer because I'm new to Stack Overflow). His answer is this:


[密码]与self.password相同。 ActiveRecord定义方法而不是实例变量来访问与数据库有关的内容。这就是为什么您无法使用@password访问它的原因。

It [password] is the same as self.password. ActiveRecord defines methods, not instance variables to access stuff related to the database. That's why you cannot access it with @password.

但是我看到的回调方法总是在模型的类中定义的,应该让他们访问实例变量,对吗?他还这样说:

But the callback methods I've seen are always defined in the model's class, which should give them access to instance variables, right? He also says this:


PS:回调只是对对象的方法调用。唯一的区别是Rails是为您而不是您自己调用的。

PS: Callbacks are only method calls on your object. The only difference is that Rails calls them for you, not yourself.

所以他也许意味着没有调用回调方法从对象的引用?例如。而不是称为 model_instance.callback_method ,它只是称为 callback_method ?如果是类实例方法,如何在不引用该类实例的情况下找到callback_method?即使以这种方式工作,它怎么会知道 self.variable 是什么?

So does he maybe mean that the callback methods aren't call from a reference to the object? E.g. rather than calling as model_instance.callback_method, it is just called as callback_method? How would callback_method be found without a reference to an instance of the class if it is a class instance method? And even if it did work this way, how would it know what self.variable was?

推荐答案


您不能直接在Active Record回调中访问实例变量吗?

can you not access instance variables directly in an Active Record callback?

可以从任何实例方法(包括那些用作ActiveRecord回调的实例方法)中访问实例变量。

You can access instance variables from any instance method, including those used as ActiveRecord callbacks.


此外,我还没有没有为这个特定的变量定义访问器函数,那么当我说self.variable或变量(我已经尝试过这两个方法,并且都在赋值的LHS之外都起作用)时会发生什么?

Also, I haven't defined an accessor function for this particular variable, so what actually happens when I say self.variable or variable (I've tried both, and both work aside from the LHS of an assignment)?

首先,了解两种语法之间的区别很重要。 variable = 123 会将值 123 分配给局部变量。 self.variable = 123 会在self上调用名为 variable = 的方法并传递 123 作为参数。

First, it is important to know what the difference between the two syntaxes. variable = 123 will assign the value 123 to a local variable. self.variable = 123 will call a method named variable= on self and pass 123 as an argument.

> class Foo
>   def x=(value)
>     puts "Foo#x called with #{ value }"
>   end
>
>   def bar
>     x = 123       # local variable assignment, `x` only exists inside the `bar` method.
>     self.x = 456  # calls `x=` 
>   end
> end

> Foo.new.bar
Foo#x called with 456

调用令人困惑的是,用隐式接收器调用的方法与引用局部变量共享相同的语法。

Something that can be a bit confusing is that methods invoked with an implicit receiver shares the same syntax with referencing a local variable.

> class Bar
>   def x
>     "In method x"
>   end
>
>   def foo
>     # No local variable `x` has been initialized yet, so references to `x` will call the method with that name.
>     puts x           # calls method `x` and prints "In method x".
>                      # This example is equivalent to `puts self.x`.
>
>     x = "Hello"      # Now that a local variable is defined it will hide the method `x`.
>     puts x           # references the local variable and prints "Hello".
>     puts self.x      # calls the method `x` and prints "In method x".
>   end
> end

> Bar.new.foo
In method x
Hello
In method x

第二,您需要知道ActiveRecord为模型表的每一列创建访问器方法。假设我有一个模型 User(id:整数,name:字符串,age:整数)。 ActiveRecord将定义实例方法 id 名称 age 读取属性和 id = name = age = 设置属性。

Second, you need to know that ActiveRecord creates accessor methods for each column of your model's table. Let's say that I have a model User(id: integer, name: string, age: integer). ActiveRecord will define instance methods id, name and age to read the attributes and id=, name= and age= to set the attributes.

实例变量完全是另外一回事。您无法使用实例变量(例如 @id @name @age

Instance variables are something else entirely. You cannot access the database attributes with instance variables like @id, @name, @age.


那么他也许意味着不是从对对象的引用中调用了回调方法吗?

So does he maybe mean that the callback methods aren't call from a reference to the object?

否,ActiveRecord回调确实确实在对象上调用实例方法。

No, ActiveRecord callbacks do indeed invoke instance methods on the object.

这篇关于为什么我不能在Active Record回调中直接访问实例变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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