2013-03-05 7 views
15

Ho una domanda ActiveRecord per esempio come questo:Aggiunta di parametri a un ambito

@result = stuff.limit(10) 

dove roba è una query record attivo con cui clausole, ORDER BY ecc ...

Ora ho pensato perché passare numeri magici come quello al controller? Quindi pensi che sia una buona pratica definire un ambito per "limit (10)" e usarlo invece? e come sarebbe la sintassi?

+0

non credo che un campo di applicazione è rilevante. Forse una costante in Model.rb se il tuo limite appare in più punti (lascia la costante 'MAX_ITEMS_PER_PAGE') – MrYoshiji

risposta

1

Lo scopo sarebbe simile a qualsiasi altro (anche se si può preferire un metodo di classe), ad esempio,

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 

Se si sempre (o "quasi" sempre) vuole quel limite, utilizzare un ambito predefinito:

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 

Per saltare l'ambito predefinito:

> Stuff.unscoped.all.size 
=> 8 
13

Bene Scopes sono pensati per questo

Scoping consente di specificare le query Arel di uso comune, che è possibile fare riferimento come metodo invita oggetti o modelli dell'associazione. Con questi ambiti, è possibile utilizzare tutti i metodi precedentemente trattati come dove, si unisce e include. Tutti i metodi di ambito restituiranno un oggetto ActiveRecord :: Relation che consentirà la chiamata di ulteriori metodi (come altri ambiti).

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

Quindi, se si sente che ci sono alcune query comuni che si hanno, o avete bisogno di un qualche tipo di concatenamento nelle query che sono comuni a molti. Allora ti suggerirò di andare per scopi per evitare la ripetizione.

Ora per rispondere come il campo di applicazione sarà simile nel tuo caso

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

Ci sono infatti molteplici modi di fare tali, metodi di classe sono uno come sottolineato da @ Dave Newton. Se si desidera utilizzare gli ambiti, ecco come fare:

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

O con le Ruby 1.9 "stabby" sintassi lambda e più argomenti:

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

Se vuoi conoscere le differenze più profonde tra ambiti e metodi di classe, controlla this blog post.

Spero che aiuti. Saluti!

+1

+1 per mostrare come usare un parametro; Non ero sicuro di dovermi preoccupare o meno. –

+2

piccolo trucchetto nell'esempio precedente di stabda lambda: non c'è spazio tra l'operatore di stab e la parentesi che apre la lista degli argomenti. – Jacob

+1

@Jacob Mi sono imbattuto in questo. Modifica la sua risposta per rimuovere lo spazio. –

12

parametri passano in Rails portata

definizione del campo di applicazione

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

metodo di chiamata

name_of_scope(parameter_name) 
0

Ambito nel modello di Rails con il parametro:

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

Oppure:

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