簡體   English   中英

使用lambda的活動記錄中的作用域-在Rails控制台中不返回任何方法錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM