Инкапсуляция SQL в named_scope - PullRequest
       23

Инкапсуляция SQL в named_scope

9 голосов
/ 26 сентября 2008

Мне было интересно, есть ли способ использовать "find_by_sql" в named_scope. Я хотел бы рассматривать пользовательский sql как named_scope, чтобы я мог связать его с моими существующими named_scopes. Это также было бы хорошо для оптимизации фрагмента SQL, который я часто использую.

Ответы [ 3 ]

10 голосов
/ 08 октября 2008

Хотя вы можете поместить любой SQL, который вам нравится, в условия именованной области, если вы затем вызовете find_by_sql, тогда «области действия» будут отброшены.

Дано:

class Item
  # Anything you can put in an sql WHERE you can put here
  named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
end

Это работает (просто вставляет туда строку SQL - если у вас есть более одного, они соединяются с AND)

Item.mine.find :all
=> SELECT * FROM items WHERE ('user_id' = 887 and IS_A_NINJA() = 1)

Однако, это не

Items.mine.find_by_sql 'select * from items limit 1'
=> select * from items limit 1

Так что ответ "Нет". Если вы думаете о том, что должно происходить за кулисами, тогда это имеет большой смысл. Чтобы построить рельсы SQL, нужно знать, как они сочетаются друг с другом.
Когда вы создаете нормальные запросы, все select, joins, conditions и т. Д. Разбиваются на отдельные части. Rails знает, что он может добавлять вещи в условия, не влияя на все остальное (как работают with_scope и named_scope).

Однако с find_by_sql вы просто даете рельсам большую строку. Он не знает, что и куда, поэтому небезопасно входить и добавлять то, что нужно будет добавить для работы областей.

1 голос
/ 29 мая 2009

Это не совсем соответствует тому, о чем вы спрашивали, но вы можете исследовать 'contruct_finder_sql'. Это позволяет вам получить SQL с именованной областью действия.

named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
named_scope :additional {
  :condtions => mine.send(:construct_finder_sql,{}) + " additional = 'foo'"
}
0 голосов
/ 26 сентября 2008

уверен, почему нет

: named_scope: условия => [ваш sql]

...