问题:我什么时候需要在Rails的模型中使用self?
我的一个模特中有一个set
方法。
class SomeData < ActiveRecord::Base
def set_active_flag(val)
self.active_flag = val
self.save!
end
end
当我这样做时,一切正常。但是,当我这样做时:
class SomeData < ActiveRecord::Base
def set_active_flag(val)
active_flag = val
save!
end
end
active_flag值不会改变,而是静默失败。谁能解释一下?
我找不到任何重复项,但如果有人发现一个也没问题的话。
答案 0 :(得分:59)
当你在调用方法的实例上执行操作时,使用self。
使用此代码
class SocialData < ActiveRecord::Base
def set_active_flag(val)
active_flag = val
save!
end
end
您正在定义一个名为active_flag的全新范围的局部变量,将其设置为传入的值,它与任何东西都没有关联,因此当方法结束时它会立即丢失,就像它从未存在过一样。
self.active_flag = val
但是告诉实例修改自己的名为active_flag的属性,而不是一个全新的变量。这就是它起作用的原因。
答案 1 :(得分:51)
这是因为范围界定而发生的。如果您在某个方法中,并尝试设置这样的新变量:
class SomeData < ActiveRecord::Base
def set_active_flag(val)
active_flag = val
end
end
您正在创建一个存在于set_active_flag内的全新变量。一旦完成执行,它就会消失,而不是以任何方式改变self.active_flag
(实际的实例变量)。
HOWEVER (这让我感到困惑):当您尝试读取 ruby中的实例变量时,如下所示:
class SomeData < ActiveRecord::Base
def whats_my_active_flag
puts active_flag
end
end
您实际上会返回self.active_flag
(实际的实例变量)。
原因如下:
Ruby会尽其所能避免返回nil
。
active_flag
whats_my_active_flag
active_flag
?但是,如果您在active_flag
中定义whats_my_active_flag
,然后要求它,则会再次执行这些步骤:
active_flag
whats_my_active_flag
在任何一种情况下,除非您明确说明,否则不会更改 self.active_flag
的值。
描述此行为的一种简单方法是“它不想让您失望”并返回nil
- 所以它会尽力找到它所能做到的。
与此同时,“它不想搞乱你不打算改变的数据”,因此它不会改变实例变量本身。
希望这有帮助!
答案 2 :(得分:1)
确保您使用setter方法而不是确定新变量的范围。这是一个Ruby和AR使用细节,经常让人们吵架(另一个是(错误地)使用实例变量)。
请注意,虽然我理解抽象的愿望,但已经有update_attributes!。
还有toggle!,它可能更好,取决于您与旗帜的接口。
答案 3 :(得分:0)
When use active_flag = val
ruby thought your are define a local variable, the best way is self.active_flag = val
, if you got it, hope you know that send(:active_flag=, val)
will works too.