【问题标题】:local methods act differently when called with/without self. Why?使用/不使用 self 调用时,本地方法的行为会有所不同。为什么?
【发布时间】:2025-11-30 00:00:02
【问题描述】:

我的模型名为User,与UserFilterhas_many 关系。 UserFilterUserbelongs_to 关系。

在用户模型中,我有一个名为update_user_filters(filter_params_array)的方法

这个方法像这样修改user_filters

def update_user_filters(filter_params_array)
  new_filters = []
  old_filter = user_filters 

  filters_params_array.each do |filter_params|
    if filter_params[:id].blank? #if the filter does not yet exist
      new_filters << UserFilter.new(filter_params)
    end
  end
  user_filters = new_filters
end

这会将user_filters 设置为预期值,但保存后不会更新数据库中的user_filters

但是,如果我将分配更改为以下内容。谁能解释这是为什么?

self.user_filters = new_filters

请注意,当我第一次在模型中引用 user_filters 时,会在数据库中进行选择,所以我不确定这个本地方法在使用 self 和没有 self 时的工作方式有何不同

【问题讨论】:

标签: ruby-on-rails ruby


【解决方案1】:

user_filters 只是创建一个局部变量。 self.user_filters 将其分配给对象。你可能想要@user_filters = ...

【讨论】:

  • 所以我有点困惑。如果 user_filters 和 user_filters= 是由活动记录动态定义的,它们不只是作为方法工作吗?所以调用 user_filters 我确实调用了该方法,因为我没有设置它并且它在调用时返回记录。同样,我希望 user_filters= 也可以调用活动记录生成的方法。但我猜你说的是它只是创建一个局部变量?但是如果 user_filters 只是一个局部变量,它如何具有值。注意我已经更新了上面的代码更清晰
  • old_filters 上面现在有一个过滤器数组列表,因此 user_filters 似乎不是本地的。但是,当我将其称为结尾时,它确实就像您以前的 cmets 的局部变量
  • 这是与 Ruby 混淆的常见点。看,Ruby 解释器不知道“user_filters =”是设置局部变量还是调用方法——所以它是前者。这就是为什么您需要“self.user_filters =”来确保它调用方法,而不是设置局部变量。
  • 这里有相当详细的解释rubyfleebie.com/use-self-explicitly
最近更新 更多