Ruby on rails 关联的ActiveRecord关系作用域访问属于对象
我想知道是否有一种方法可以访问ActiveRecord::Relation中关联的对象 例如,在这种关系中: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
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方法
。