with_scope & joins
Dans rails, on trouve des pépites et with_scope en est une. Une vieille pépite et toujours pas finie, je serais tenté de dire.
Par exemple, il ne tient pas compte de la clause :order.
De mon côté, j’ai besoin d’un ordre précis pour faire le merge de mes jointures.
Prenons l’exemple suivant :
class Dumb
class << self
def foo_bar
with_scope(:find => { :join => "INNER JOIN bar ON bar.id=foo.bar_id"}) do
want_foo
end
end
def want_foo
with_scope(:find => { :join => "INNER JOIN foo ON foo.id=dump.foo_id"}) do
# do your stuff
...
end
end
end
end
... INNER JOIN bar ON bar.id=foo.bar_id INNER JOIN foo ON foo.id=dump.foo_id ... ... ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'foo.bar_id' ..
On souhaite avoir l’ordre inversé genre :
... INNER JOIN foo ON foo.id=dump.foo_id INNER JOIN bar ON bar.id=foo.bar_id ...
Voici la solution :
...
do_reverse_merge_joins do
def foo_bar
with_scope(:find => { :join => "INNER JOIN bar ON bar.id=foo.bar_id"}) do
want_foo
end
end
end
...
et le patch ou l’extension comme vous voulez (testé pour rails 2.3)
ActiveRecord::Base.class_eval do
class << self
def merge_joins_with_reverse(*joins)
merge_joins_without_reverse(reverse_merge_joins? ? joins.reverse : joins)
end
alias_method_chain :merge_joins, :reverse
def do_reverse_merge_joins(&block)
set_reverse_merge_joins
result = yield
reset_reverse_merge_joins
result
end
def reset_reverse_merge_joins
set_reverse_merge_joins(nil)
end
def set_reverse_merge_joins(value = true)
Thread.current[:"#{self}_reverse_merge_joins"] = value
end
def reverse_merge_joins?
Thread.current[:"#{self}_reverse_merge_joins"]
end
end
end
Laissez un commentaire