Adding parameter to a scope

有些话、适合烂在心里 提交于 2019-12-12 07:29:50

问题


I have a ActiveRecord query for example like this:

@result = stuff.limit(10)

where stuff is a active record query with where clauses, order by, etc...

Now I thought why to pass magic numbers like that to the controller? So do you think is it a good practice to define a scope for "limit(10)" and use that instead? and how would the syntax look like?


回答1:


The scope would look like any other (although you may prefer a class method), e.g.,

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

If you always (or "almost" always) want that limit, use a default scope:

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

To skip the default scope:

> Stuff.unscoped.all.size
=> 8



回答2:


There are indeed multiple ways of doing such, class methods are one as pointed out by @Dave Newton. If you'd like to use scopes, here's how:

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

Or with the Ruby 1.9 "stabby" lambda syntax and multiple arguments:

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

If you'd like to know the deeper differences between scopes and class methods, check out this blog post.

Hope it helps. Cheers!




回答3:


Well Scopes are meant for this

Scoping allows you to specify commonly-used Arel queries which can be referenced as method calls on the association objects or models. With these scopes, you can use every method previously covered such as where, joins and includes. All scope methods will return an ActiveRecord::Relation object which will allow for further methods (such as other scopes) to be called on it.

Source: http://guides.rubyonrails.org/active_record_querying.html#scopes

So if you feel that there are some common queries which you have, or you need some kind of chaining in your queries which are common to many. Then i will suggest you to go for scopes to prevent repetition.

Now to answer how the scope will look like in your case

class YourModel < ActiveRecord::Base
  scope :my_limit, ->(num) { limit(num)} 
  scope :your_where_condition, ->(num) { where("age > 10").mylimit(num) } 
end



回答4:


Pass parameters in Rails scope

Definition of scope

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

Calling Method

name_of_scope(parameter_name)



回答5:


Scope in Rails model with parameter:

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

Or:

scope :scope_name, lambda{|parameter, ...| where(is_deleted:parameter, ...)} 


来源:https://stackoverflow.com/questions/15229000/adding-parameter-to-a-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!