ruby on rails what Override di Rails default_scope




wikipedia ruby on rails (7)

Se ho un modello ActiveRecord :: Base con un ambito di default:

class Foo < ActiveRecord::Base

  default_scope :conditions => ["bar = ?",bar]

end

C'è un modo per fare un Foo.find senza usare le condizioni default_scope ? In altre parole, puoi sovrascrivere un ambito predefinito?

Avrei pensato che usare "default" nel nome suggerisse che era sovrascrivibile, altrimenti sarebbe stato chiamato qualcosa come global_scope , giusto?


Bene, puoi sempre usare il preferito di vecchia data find_by_sql con la query completa. Ad esempio: Model.find_by_sql ("SELECT * FROM models WHERE id = 123")


In Rails 3:

foos = Foo.unscoped.where(:baz => baz)

Se tutto ciò che serve è modificare l'ordine definito in default_scope , è possibile utilizzare il metodo di reorder .

class Foo < ActiveRecord::Base
  default_scope order('created_at desc')
end

Foo.reorder('created_at asc')

esegue il seguente SQL:

SELECT * FROM "foos" ORDER BY created_at asc

Rails 3 default_scope non sembra essere sovrascritto come ha fatto in Rails 2.

per esempio

class Foo < ActiveRecord::Base
  belongs_to :bar
  default_scope :order=>"created_at desc"
end

class Bar < ActiveRecord::Base
  has_many :foos
end

> Bar.foos
  SELECT * from Foo where bar_id = 2 order by "created_at desc";
> Bar.unscoped.foos
  SELECT * from Foo;  (WRONG!  removes the "has" relationship)
> Bar.foos( :order=>"created_at asc" )  # trying to override ordering
  SELECT * from Foo where bar_id = 2 order by "created_at desc, created_at asc"

Nella mia app, utilizzando PostgreSQL, l'ordinamento nell'ambito predefinito WINS. Sto rimuovendo tutti i miei default_scope e lo codifico esplicitamente ovunque.

Pitfall Rails3!


Con Rails 3+ puoi utilizzare una combinazione di non spopolato e unione:

# model User has a default scope
query = User.where(email: "[email protected]")

# get rid of default scope and then merge the conditions
query = query.unscoped.merge(query)

Dal 4.1 puoi usare ActiveRecord::QueryMethods#unscope per combattere lo scope di default:

class User < ActiveRecord::Base
  default_scope { where tester: false }
  scope :testers, -> { unscope(:where).where tester: true }
  scope :with_testers, -> { unscope(:where).where tester: [true, false] }
  # ...
end

È currently possibile unscope l' unscope cose come:: :where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having unscope :where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having .

Ma per favore, evita di usare default_scope se puoi . È per il tuo bene.


È possibile sovrascrivere un ambito predefinito utilizzando il metodo with_exclusive_scope . Così:

foos = Foo.with_exclusive_scope { :conditions => ["baz = ?", baz] }




ruby-on-rails