[英]scopes in Active records using lambda - returns No method error in Rails Console
在我的用戶模型類中,我定義了以下兩個作用域。
scope :condition, lambda { where('updated_at >= ?', 3.day.ago) }
scope :tardy, lambda {
joins(:timesheets).group("users.id") & Timesheet.condition
}
然后我嘗試運行重裝! ,然后u = User.find 14 ,我得到以下結果。
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 14 LIMIT 1
=> #<User id: 14, login: "janu", password: "janu", password_confirmation: nil, email: "janu@gmail.com", created_at: "2013-01-03 09:47:36", updated_at: "2013-01-03 09:47:36">
然后我運行u.tardy.to_sql ,但是它返回以下錯誤。
NoMethodError: undefined method `tardy' for #<User:0x00000003cb5ea0>
from /home/local/rajesh.co/.rvm/gems/ruby-1.9.3-p327/gems/activemodel-3.2.9/lib/active_model/attribute_methods.rb:407:in `method_missing'
from /home/local/rajesh.co/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.9/lib/active_record/attribute_methods.rb:149:in `method_missing'
from (irb):64
from /home/local/rajesh.co/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.9/lib/rails/commands/console.rb:47:in `start'
from /home/local/rajesh.co/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.9/lib/rails/commands/console.rb:8:in `start'
from /home/local/rajesh.co/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.9/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
請參閱,當我按以下說明將兩個合並在一起時,也會遇到相同的錯誤。
scope :tardy, lambda {
joins(:timesheets).
where("timesheets.updated_at >= ?", 3.days.ago).
group("users.id")
}
您能幫我解決這個問題嗎? 謝謝。
您不能在特定記錄上調用作用域。 當您調用.find
,您將獲得一條特定的記錄 ,而不是可以鏈接其他作用域的關系/關聯。
如果要查找ID為14的遲到用戶,則必須顛倒方法調用的順序:
User.tardy.find(14)
您仍然將無法運行.to_sql
,因為您將再次獲得一條記錄。 如果您真的想讓SQL返回特定的按ID查找,則可以使用
User.tardy.where(:id => 14).to_sql
錯誤出在模型的范圍定義上,而meagar的答案也適用於其中一種錯誤。
scope :tardy, lambda {
joins(:timesheets).group("users.id") && Timesheet.condition
}
在上面,我指定了Timesheet.condition ,其中條件范圍必須在Timesheet模型而不是User模型中聲明,因為我需要根據時間表更新的時間對用戶進行分組。 因此,下面給出的時間表必須存在於時間表模型中。
scope :condition, lambda { where('updated_at >= ?', 3.day.ago) }
運行User.tardy ,我們將獲得滿足指定條件的所有已更新時間表的用戶 。
第二個簡單的方法是在用戶模型本身中定義一個范圍:
scope :tardy, lambda {
joins(:timesheets).
where("timesheets.updated_at >= ?", 3.days.ago).
group("users.id")
}
但是,此跨模型范圍違反了良好的面向對象設計原則:它包含確定是否更新時間表的邏輯,該時間表正確地屬於時間表類。 因此,第一種方法是優選的。
謝謝你們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.