Rails 3 получает sql из области видимости

#sql #ruby-on-rails #scope

#sql #ruby-on-rails #область видимости

Вопрос:

Есть ли способ получить sql только для области видимости? Итак, я хочу сделать что-то вроде:

    class Presentation < ActiveRecord::Base
      has_many :calls
      has_many :recordings, :through => :calls

      scope :with_recordings, joins(:calls).joins(:recordings)
   end
  

А затем сможет получить sql для этой области.

Presentations.with_recordings.sql возвращает всю инструкцию sql, включая SELECT инструкцию. Все, что я хочу, это sql, добавленный областью видимости. Полагаю, должен быть способ сделать это.

Ответ №1:

Я согласен с ctcherry в том, что это не очень полезно, но, сказав это, мне нужно было сделать это для проекта, над которым я работал. Нам нужно было дублировать sql в областях видимости, чтобы позволить нам повторно использовать sql для разных типов поиска. Вместо того, чтобы поддерживать один и тот же sql в двух разных местах, я выбираю извлечь sql из области видимости.

Приведенный ниже код — это то, что я придумал. Это некрасиво, но работает под Rails 3.0

 def extract_named_scope_clause(scope, args)
  # where_clauses will return an array of clauses for an entire relationship.
  # As this is only run a single scope, we only ever care about the first.....
  clause, *bind_vars = self.send(scope, args).where_clauses.first
  # prefix 'and ' to the string, add some spaces and append any bind variables
  if clause
    [" and #{clause} ", bind_vars]
  else
    nil
  end
end
  

Комментарии:

1. закрыть, но что мне действительно нужно, так это полный оператор, а не только предложения where . В данном случае я имею дело конкретно с объединениями, так что where_clauses на самом деле это не помогает.

Ответ №2:

На самом деле это не имело бы смысла, поскольку не существует стандартного способа представления SQL «фрагментов».

Различные виды «фрагментов» SQL, которые могут быть добавлены и которыми можно манипулировать с помощью области видимости, на самом деле не имеют четкого способа представления сами по себе, не являясь частью полной инструкции SQL. Фрагментом может быть «ПРИСОЕДИНИТЬСЯ к пользователям НА users.id = orders.user_id» или это может быть «ГДЕ active = 1». Как бы вы вернули их, если бы они не были частью полной инструкции SQL? Скорее всего, именно поэтому нет механизма для их извлечения, отличного от того, который вы уже обнаружили, который просто возвращает полный оператор SQL.