web-dev-qa-db-fra.com

Ajout de paramètre à une portée

J'ai une requête ActiveRecord par exemple comme ceci:

@result = stuff.limit(10)

où stuff est une requête d'enregistrement active avec les clauses where, order by, etc ...

Maintenant, je me suis demandé pourquoi passer des chiffres magiques comme celui-là au contrôleur? Donc, pensez-vous que c’est une bonne pratique de définir une portée pour "limit (10)" et de l’utiliser plutôt? et à quoi ressemblerait la syntaxe?

18
Bohn

La portée ressemblerait à une autre (bien que vous préfériez peut-être une méthode de classe), par exemple,

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

Si vous toujours (ou "presque" toujours) voulez cette limite, utilisez une portée par défaut:

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

Pour ignorer l'étendue par défaut:

> Stuff.unscoped.all.size
=> 8
2
Dave Newton

Il y a en effet plusieurs façons de faire, les méthodes de classe sont une comme l'a souligné @Dave Newton. Si vous souhaitez utiliser des étendues, voici comment:

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

Ou avec la syntaxe lambda "stabby" Ruby 1.9 et ses arguments multiples:

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

Si vous souhaitez connaître les différences plus profondes entre les portées et les méthodes de classe, consultez cet article de blog .

J'espère que ça aide. À votre santé!

41
Andre Bernardes

Les oscilloscopes sont destinés à cette

Le cadrage vous permet de spécifier les requêtes Arel couramment utilisées qui peuvent être référencées en tant qu'appels de méthodes sur les objets d'association ou les modèles. Avec ces portées, vous pouvez utiliser toutes les méthodes couvertes précédemment, telles que où, se joint et inclut. Toutes les méthodes d'étendue renverront un objet ActiveRecord :: Relation qui permettra à d'autres méthodes (telles que d'autres étendues) d'y être appelées. 

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

Donc, si vous avez l’impression que vous avez des requêtes communes, ou si vous avez besoin d’une sorte de chaînage dans vos requêtes qui est commun à beaucoup. Ensuite, je vous suggérerai d’utiliser des oscilloscopes pour éviter les répétitions.

Maintenant, pour savoir à quoi ressemblera la portée dans votre cas

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

Paramètres de passage dans la portée de Rails

Définition du champ d'application

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

Méthode d'appel

name_of_scope(parameter_name)
15
deep gupta

Portée dans le modèle Rails avec paramètre:

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

Ou: 

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