【问题标题】:Issues with Ruby's defined? operator in RailsRuby 定义的问题? Rails 中的操作员
【发布时间】:2012-12-06 23:42:41
【问题描述】:

我的 Writer 类上有一个使用定义的实例方法?运算符检查是否定义了posted_posts:

def performance_score
  logger.debug posted_posts
  logger.debug defined?(posted_posts)
  unless defined?(posted_posts)
    ...
  else
    ...
  end
end

在我的控制器中,我有一个 writers 实例,定义如下:

@writers = Writer.select("writers.*, p.total_posts, p.posted_posts").joins(...)

当我调用@writers.performance_score 时,第一个logger.debug 行显示我有4 个posted_posts,但第二个打印出nil。此外,它进入了除非部分而不是其他部分。

为了测试这一点,我将posted_posts 存根为4。这从第一个logger.debug 行打印出4,第二个logger.debug 表示它被定义为一个方法。此外,它确实进入了 else。

您能帮我理解为什么我的 Rails 应用程序会失败吗?

【问题讨论】:

  • @writers = @writers.select 看起来很有趣。什么是@writers(选择前后)?通常,我们会使用Writer has_many :total_posts 之类的东西,它可以让ActiveRecord 处理respond_to? :total_poststrue
  • 只是一个小注——unless / else 不清楚,可以随时改写为if / else
  • 我将 .joins(...) 添加到我最初的问题中,以使其更清楚我在做什么。如果有帮助,这是实际的连接:.joins("LEFT OUTER JOIN (SELECT writer_id, count(*) as total_posts, sum(case when state = 'posted' then 1 else 0 end) as posted_posts, sum(case when state = 'rejected' then 1 else 0 end) as rejected_posts, max(created_at) as last_created_post FROM posts WHERE customer_id != 11 GROUP BY writer_id) as p ON p.writer_id = writers.id")

标签: ruby-on-rails ruby operators defined


【解决方案1】:

实际上很可能失败,因为从您的 AREL select 语句返回的关系使用 method_missing 魔法从调用中返回一个值。这与defined 不同。当您在测试对象上模拟/存根“方法”时,很可能会使用正在创建已定义函数的 define_method 函数。

这可能会做你想做的事。

if respond_to?(:posted_posts)
  ...
else
  ...
end

【讨论】:

  • 您有什么建议可以帮助我获得想要的结果吗?
  • 您是否尝试过使用respond_to?? AREL 似乎很可能会设置一个适当的respond_to? 以配合其method_missing
  • 非常感谢您的帮助和快速响应,但 respond_to? 返回 false。
  • 可能是respond_to_missing?
  • 其实安德鲁,你的回答很完美。我在posted_posts 之前忘记了冒号。我最终使用了 has_attribute?因为它似乎更具体到我正在寻找的东西,但非常感谢。
【解决方案2】:

在你查询 AR 对象后不要使用相同的变量名,

@results = @writers.select("writers.*, p.total_posts, p.posted_posts")

然后在你的控制器中调用@results.performance_score

【讨论】:

  • 这是将作用域链接在一起的标准做法。看看 Ryan Bates 的这个例子:def index @products = @products.includes(:category).page(params[:page]) end
  • 我更改了查询以防止任何其他混淆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
相关资源
最近更新 更多