在不使用 self 的情况下从模型设置属性不起作用

发布于 2024-10-25 00:42:23 字数 705 浏览 1 评论 0原文

设备模型具有以下属性:名称、版本和全名

全名是名称+版本:

class Device < ActiveRecord::Base
  def prepare
    full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

当我执行以下操作时:

d = Device.new :name => "iPhone", :version => "4"
d.prepare
d.full_name # get nil

“full_name”属性为nil

当我使用“self”时,它有效:

class Device < ActiveRecord::Base
  def prepare
    self.full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

执行“prepare”我得到“ iPhone 4”为“full_name”属性。

这里的一些人告诉我,避免在类方法中使用“self”是一个好方法。 但这会带来麻烦。

问题是 - 为什么不使用“self”它就不起作用?

Device model has following attributes: name, version and full_name

Full name is name + version:

class Device < ActiveRecord::Base
  def prepare
    full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

When i do following:

d = Device.new :name => "iPhone", :version => "4"
d.prepare
d.full_name # get nil

I get nil for "full_name" attribute

When I'm using "self", it works:

class Device < ActiveRecord::Base
  def prepare
    self.full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

Doing "prepare" i get "iPhone 4" for "full_name" attribute.

Some people here told me, that it's a good manner to avoid using "self" inside class methods.
But this brings trouble.

The question is - why it does't works without using "self" ?

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

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

发布评论

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

评论(3

谜兔 2024-11-01 00:42:23

在这些情况下你必须使用 self,我不认为这是一个麻烦。如果您使用self,那么解释器就会知道您引用了对象的属性。如果您不使用 self ,则意味着它只是一个局部变量,在方法完成后不会存储在任何地方。这是正常行为。您还可以使用 self[:full_name]= ... 作为 setter 方法,但在这种情况下并不重要。

更新

@AntonAL

因为 getter 方法无需 self. 即可识别。

当您尝试使用 name 属性时,解释器将在当前方法中查找局部变量。如果没有找到,则查找实例属性。示例:

def your_method
  self.name = 'iPhone'
  puts name
  #iPhone
  name = 'iPod'
  puts name
  #iPod
  puts self.name
  #iPhone
end

iPhone 将存储在对象实例的 name 属性中。方法完成后,iPod 将丢失。

In these cases you have to use self, I don't think it's a trouble. If you are using self then the interpreter will know that you refer to the object's attribute. If you don't use self it means that it's just an local variable which is not stored anywhere after the method finishes.That's the normal behavior. You can also use self[:full_name]= ... as a setter method, but in this case doesn't really matter.

Update

@AntonAL

Because the getter methods are recognized without the self..

When you try to use the name attribute, the interpreter will look for a local variable within the current method. If doesn't finds then looks for an instance attribute. Example:

def your_method
  self.name = 'iPhone'
  puts name
  #iPhone
  name = 'iPod'
  puts name
  #iPod
  puts self.name
  #iPhone
end

And iPhone will be stored in your object instance's name attribute. And iPod will be lost after the method finishes.

等待我真够勒 2024-11-01 00:42:23

当您使用setter时,您需要使用self,否则Ruby会将其解释为正在定义的新局部变量full_name

对于getters,我们不需要调用self,因为Ruby首先搜索局部变量full_name,当它没有局部变量full_name时,它将搜索方法 full_name 并获取 getter。如果您定义了局部变量full_name,它将返回局部变量的值。

这在 上一个问题

When you use setters, you need to use self because otherwise Ruby will interpret it as a new local variable full_name being defined.

For getters, we dont need to call self because Ruby first search for a local variable full_name and when it does not have a local variable full_name, it will search for a method full_name and will get the getter. If you have a local variable defined full_name, it will return the value of local variable.

This is explained better in a previous question

一笔一画续写前缘 2024-11-01 00:42:23

这是预料之中的,因为这就是 ActiveRecord 的设计工作原理。如果您需要设置任意属性,那么您必须使用不同类型的对象。

例如,Ruby 提供了一个名为

开放结构

允许您创建可以分配任意键和值的对象。如果您想从没有 self 的属性中获取值,它将为您提供具有实例全局变量属性的 OpenStruct 类的实例。但如果你想设置新属性,它会使用新属性创建 OpenStruct 类的新实例。如果没有 self,您将拥有旧的 OpenStruct 对象,它没有属性,并且会给您带来错误。

您可能需要使用此类库,然后仅在需要保存到数据库时将对象转换为相应的 ActiveRecord 实例。

不要尝试对 ActiveRecord 进行建模以使其按照您刚才描述的方式运行,因为它根本就不是为了以这种方式运行而设计的

This is expected because it's how ActiveRecord works by design. If you need to set arbitrary attributes, then you have to use a different kind of objects.

For example, Ruby provides a library called

OpenStruct

that allows you to create objects where you can assign arbitrary key and values. If you want get value from attribute without self, it's will give you instance of class OpenStruct with instance global variable attribute. But if you want set new attribute, it`s create new instance of class OpenStruct with new attributes. Without self you will have are old OpenStruct object which don't have attribute and will gave you error.

You may want to use such library and then convert the object into a corresponding ActiveRecord instance only when you need to save to the database.

Don't try to model ActiveRecord to behave as you just described because it was simply not designed to behave in that way

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