【问题标题】:Custom scope not returning any results自定义范围不返回任何结果
【发布时间】:2013-09-16 19:28:03
【问题描述】:

基本关联设置(注意,Customer 是 Person 模型的扩展):

Customer has_many :orders
Order belongs_to :customer

在 Customer.rb 内部,我有以下类方法:

# SCOPE
def self.ordered_in_90_days
  joins(:orders).where('orders.created_at > ?', 90.days.ago)
end

在我的测试中,我有以下代码创建一个新订单(自动创建一个客户,感谢 FactoryGirl),然后使用上面定义的 Customer 模型的 self 方法:

it "finds customers who have ordered within the last 90 days" do
  @order     = FactoryGirl.create(:order, created_at: 50.days.ago)
  @customer  = @order.customer

  Customer.count.should == 1  #passes
  Order.count.should == 1     #passes

  puts Customer.all.to_yaml   #for debugging, see below
  puts Order.all.to_yaml      #for debugging, see below

  Customer.ordered_in_90_days.should == [@customer]   #fails! returns: []
end

正在创建客户和订单,但方法调用中没有返回任何内容(空数组)。我错过了什么?

以下是有关工厂的一些附加信息:

FactoryGirl.define do
    factory :customer do
        first_name "Wes"
        last_name "Foster"
        type "Customer"
    end

    factory :order do
        customer
    end
end

这是 Customer 和 Order 的调试输出(请记住,Customer 是 Person 的扩展,所以这就是您看到 person_id 而不是 customer_id 的原因):

---
- !ruby/object:Customer
  attributes:
    id: 1
    first_name: Wes
    last_name: Foster
    type: Customer
    created_at: 2013-09-16 21:54:26.162851000 Z
    updated_at: 2013-09-16 21:54:26.162851000 Z
    middle_name: 
---
- !ruby/object:Order
  attributes:
    id: 1
    person_id: 
    created_at: 2013-07-28 21:54:26.135748000 Z
    updated_at: 2013-09-16 21:54:26.192877000 Z

(客户

【问题讨论】:

  • 尝试在该测试示例的开头放置一个调试器语句,然后运行测试并检查所有相关对象以确保它们的属性完全符合您的预期。您确定您得到了完全正确的订单、客户和 created_at 吗?
  • 另外,也许发布您的工厂订单以便我们可以看到该代码。
  • 我认为您的类方法/范围没有任何问题:我在我的一个应用程序中尝试了针对某些模型的类似范围,并且效果很好。
  • 谢谢卡洛斯。我添加了工厂和调试信息。希望你能看到我看不到的东西:)
  • 太好了,看看下面我的回答!

标签: ruby-on-rails ruby-on-rails-3 join associations factory-bot


【解决方案1】:

调试输出确实表明了问题!查看订单检查:您的 person_id 为空白。

首先,即使 Customer 是 Person 的子类/扩展,Order belongs_to :customer 也会告诉 ActiveRecord 查找 customer_id,而不是 person_id。您是否指示应在 Order 模型上以非默认方式配置关联?

否则,我认为您可能错误地处理了 Order 工厂中的别名关联引用。我没有在我的项目中使用 factory_girl 关联别名引用——我试图将关联排除在我的工厂之外——但我会使用 factory_girl 文档验证您的方法:Association Aliases

我个人会在你的测试示例中尝试这个:

it "finds customers who have ordered within the last 90 days" do
  @customer  = FactoryGirl.create(:customer)
  @order     = FactoryGirl.create(:order, created_at: 50.days.ago, customer: @customer)

  Customer.count.should == 1  
  Order.count.should == 1     

  Customer.ordered_in_90_days.should == [@customer]
end

在您的示例中显式设置@order.customer 可以消除工厂依赖性和复杂性。

旁注
如果您想在您的工厂中保留关联别名方法,并在其他测试中依赖该关联,我建议您编写一个单独的测试来验证工厂关系是否正确实例化:

@order = create(:order)
expect(@order.customer).to be_a(Customer)

或者类似的...

【讨论】:

  • 谢谢卡洛斯。是的,我为 Order 和 Customer 模型分配了 foreign_key 属性。问题似乎在于 FactoryGirl 在创建订单时没有关联订单和客户。我不敢相信我在 yaml 中错过了它!您为我指明了正确的方向,并且按照您的建议,我重新排序了我的订单和客户的创建。现在一切似乎都在顺利进行。并感谢有关订单/客户关联测试的提示。最后,在这种情况下不需要 FactoryGirl 别名。谢谢!
  • 太好了,很高兴我能帮上忙!我很高兴有机会更新我的 FactoryGirl 知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
相关资源
最近更新 更多