25

我有一个 ActiveRecord 查询,例如:

@result = stuff.limit(10)

where stuff 是带有 where 子句、order by 等的活动记录查询...

现在我想为什么要将这样的幻数传递给控制器​​?那么您认为为“limit(10)”定义一个范围并改用它是一个好习惯吗?语法会是什么样子?

4

5 回答 5

53

确实有多种方法可以做到这一点,@Dave Newton 指出的类方法就是其中之一。如果您想使用范围,方法如下:

scope :max_records, lambda { |record_limit|
  limit(record_limit)
}

或者使用 Ruby 1.9 “stabby” lambda 语法和多个参数:

scope :max_records, ->(record_limit, foo_name) {   # No space between "->" and "("
  where(:foo => foo_name).limit(record_limit)
}

如果您想了解作用域和类方法之间更深层次的区别,请查看这篇博文。

希望能帮助到你。干杯!

于 2013-03-05T16:52:12.143 回答
23

Well Scopes 就是为此而生的

范围界定允许您指定常用的 Arel 查询,这些查询可以作为关联对象或模型上的方法调用来引用。通过这些作用域,您可以使用之前介绍的所有方法,例如 where、joins 和 include。所有作用域方法都将返回一个 ActiveRecord::Relation 对象,该对象将允许在其上调用更多方法(例如其他作用域)。

来源: http: //guides.rubyonrails.org/active_record_querying.html#scopes

因此,如果您觉得您有一些常见的查询,或者您需要在您的查询中使用一些对许多人来说很常见的链接。然后我会建议你去寻找范围以防止重复。

现在回答范围在您的情况下的样子

class YourModel < ActiveRecord::Base
  scope :my_limit, ->(num) { limit(num)} 
  scope :your_where_condition, ->(num) { where("age > 10").mylimit(num) } 
end
于 2013-03-05T16:44:17.657 回答
17

在 Rails 范围内传递参数

范围的定义

scope :name_of_scope, ->(parameter_name) {condition whatever you want to put in scope}

调用方法

name_of_scope(parameter_name)
于 2014-01-06T13:41:21.537 回答
2

范围看起来像任何其他的(尽管您可能更喜欢类方法),例如,

class Stuff < ActiveRecord::Base
  def self.lim
    limit(3)
  end
end

> Stuff.lim.all
=> [#<Stuff id: 1, name: "foo", created_at: "2013-03-01 17:58:32", updated_at: "2013-03-01 17:58:32">,
 #<Stuff id: 2, name: "bnar", created_at: "2013-03-01 17:58:32", updated_at: "2013-03-01 17:58:32">,
 #<Stuff id: 3, name: "baz", created_at: "2013-03-01 17:58:32", updated_at: "2013-03-01 17:58:32">]
> Stuff.all.length
=> 8

如果您总是(或“几乎”总是)想要该限制,请使用默认范围:

class Stuff < ActiveRecord::Base
  attr_accessible :name, :hdfs_file

  default_scope limit(3)
end

> Stuff.all
=> [#<Stuff id: 1, name: "foo", created_at: "2013-03-01 17:58:32", updated_at: "2013-03-01 17:58:32">,
 #<Stuff id: 2, name: "bnar", created_at: "2013-03-01 17:58:32", updated_at: "2013-03-01 17:58:32">,
 #<Stuff id: 3, name: "baz", created_at: "2013-03-01 17:58:32", updated_at: "2013-03-01 17:58:32">]
> Stuff.all.length
=> 3

要跳过默认范围:

> Stuff.unscoped.all.size
=> 8
于 2013-03-05T16:48:02.450 回答
2

带参数的 Rails 模型中的范围:

scope :scope_name, -> (parameter, ...) { where(is_deleted: parameter, ...) }  

或者:

scope :scope_name, lambda{|parameter, ...| where(is_deleted:parameter, ...)} 
于 2016-08-04T09:28:32.383 回答