Ruby on rails 关联的ActiveRecord关系作用域访问属于对象

Ruby on rails 关联的ActiveRecord关系作用域访问属于对象,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我想知道是否有一种方法可以访问ActiveRecord::Relation中关联的对象 例如,在这种关系中: class Customer < ActiveRecord::Base has_many :invoices end class Invoice < ActiveRecord::Base belongs_to :customer def self.check_new # do something rescue => e MyLogg

我想知道是否有一种方法可以访问ActiveRecord::Relation中关联的对象

例如,在这种关系中:

class Customer < ActiveRecord::Base
  has_many :invoices
end


class Invoice < ActiveRecord::Base
  belongs_to :customer

  def self.check_new
    # do something
  rescue => e
    MyLogger.log_error_for(customer, __method__)
  end
end
然后发生错误。我想记录此特定客户的此错误

我知道我可以在class方法中使用
scoped
获取发票,并调用
scoped.first.customer
。 但这看起来有点脏。此外,如果没有任何发票,这将不是一个解决方案

如果有办法做到这一点,我不是舒尔,但在scoped上进行检查会给您一些类似的信息:

SELECT * FROM SOME JOIN WHERE customer_id = 1
  customer = Customer.first
  customer.invoices.check_new
  InvoiceManager.check_new(Customer.first.invoices)
因此有一种对客户对象的引用。 有人能帮忙吗

更新: 这只是一个例子。实际上我不做日志记录之类的。当然,它们是更好的日志记录方法。
我只想将更新集合的代码放在模型类中。像普通客户一样。首先。发票。创建即可。并且可以访问此关系的父项。

可能类似于:

  customer = Customer.first
  customer.invoices.each {|invoice| invoice.check_new}
还有一些其他想法:

更新:

我认为,
Customer.first.invoices.check\u new
会抛出一个错误,因为您试图调用集合上的类方法

^^^

这是不正确的。看

你也许可以按你的要求去做。我不知道。这似乎真的很复杂。我确信您有一个有效的用例。但是,它是什么还不清楚。我仍然可能会这样做:

SELECT * FROM SOME JOIN WHERE customer_id = 1
  customer = Customer.first
  customer.invoices.check_new
  InvoiceManager.check_new(Customer.first.invoices)
这不能回答您的问题,所以如果它不适合您的用例,请道歉

结束更新

所以,
.check\u new
应该是一个实例方法。大致如下:

  class Invoice < ActiveRecord::Base

    def check_new
      if errors = check_for_errors
        MyLogger.log_error_for(customer, __method__, errors)
      end
    end

    private 

    def check_for_errors
      ... error checking logic
    end

  end       
这样,您的
Invoice
模型就回到了只处理数据库交互的状态,并且您的业务逻辑完全分离了

此外,使用这种方法,控制器根本不需要访问
Invoice
类或其实例。或者,对
Invoice
类有任何了解。这改进了
控制器
模型
层之间的分离。并减少对
发票的潜在下游更改


最后,我发现测试PORO比测试控制器容易得多。

您有点困惑

为了简单起见,这里有一个工作示例

什么是控制器

def show  #(no matter which one, could be index or anything with GET request)
  @user = Customer.first
  @invoice = @user.invoices.first   #works with the properly set up belongs_to and has_many associations which you did well
  @invoice.check_new  #it is called on an instance (object) of invoice class, not on the class it self as you do
end
类别发票

 def check_new  #if you put self before the method name then it is a class method and self is equal to Invoice (class name), if you don't then it's an instance method
   self.do_something  #now self means the instance itself which is the single @invoice at the moment. If you use self within the class method then this self would mean Invoice class just like in the name of the method
 end
基本上,当您处理类本身时,您使用类方法,而不尝试对单个实例执行任何操作。比如说

@invoices = Invoice.limit(10).order(create_at: :desc) 
在这里,您试图找到类的一堆实例,所以不能在单个实例上使用方法。但是假设您想修改一些实例的属性。因此,您必须转到该实例并将其更改为:

@invoices.each do |invoice|
  invoice.check_new
  invoice.amount = 10
end
在这里,一次更改一个实例,因此需要实例方法


我建议你去谷歌看看有什么不同。这在rails中非常关键

此解决方案将解决这个特定问题(以更好的方式设计corse)。但这只是一个例子,也许不是最好的,抱歉。这篇文章的主题是主要的问题。对集合调用类方法不会引发错误,它只调用该方法。很高兴能提供一些帮助。祝你好运如果你愿意,记得“接受”。顺便说一句,我认为你的例子是可行的-所以,干得不错。你在ActiveRecord::Relation上调用类方法是正确的。我会更新我的帖子。谢谢你的更新,我已经知道了相关的帖子,可惜它没有回答我的问题。作用域中存在与客户的关系,如何访问作用域中的此关系。确定。提供了一个更新。我确信您有一个有效的用例。我不知道答案。道歉。继续举个例子:我不想在发票实例上调用check_new。我想在客户的“发票上/所有发票上”给他们打电话。我对这个话题做了一些研究,并做了一些变通。你想用这个方法做什么?如果您想处理一个或多个实例的属性,那么您将使用实例方法。首先,您必须使用类方法查找给定的实例
@customer=customer.first
是您在本例中调用的class方法
customer class
<代码>@invoices=@customer.invoices
是一个实例方法,因为您在
@customer
实例上调用它。然后,您对每个发票都迭代了许多
@invoices
,但由于迭代,您将调用一个实例方法,如
invoices.some\u方法