Мои запросы направляющих начинают быть сложными, я должен переключиться на необработанные SQL-запросы?Чем Вы занимаетесь?

Я использую этот термин сам, и это потому, что это мой стиль, я не использую boost, stl или некоторые другие вещи, даже не стандартные библиотеки C ++, такие как «cout» и «cin», я программирую на C, но использование классов, шаблонов и других (не библиотечных) функций для моего преимущества.

Я могу сказать, что я не мастер C, не мастер C ++, но я действительно хорош в этом конкретном стиле, который я использую с 10 лет назад. (и я все еще поправляюсь!)

7
задан Tony 17 June 2009 в 18:50
поделиться

2 ответа

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

Использование метода find без фрагментов SQL обычно обеспечивает лучшую ремонтопригодность. В вашем примере попробуйте:

Book.find(:all,
  :conditions => ["created_at >= ? AND created_at <= ? AND updated_at <= ?", 
                  date1, date2, date3]
  :include => :carts)

: inlude =>: carts выполнит соединение, если вы добавили has_many: carts в свою модель Book . Как видите, не требуется много SQL. Даже кавычки и экранирование ввода можно оставить Rails, при этом все еще используя литералы SQL для обработки операторов > = и <= .

Пойдем немного дальше, вы можно сделать это еще яснее:

class Book < AciveRecord::Base
  # Somewhere in your Book model:
  named_scope :created_between, lambda { |start_date, end_date|
    { :conditions => { :created_at => start_date..end_date } }
  }
  named_scope :updated_before, lambda { |date|
    { :conditions => ["updated_at <= ?", date] }
  }
  # ...
end

Book.created_between(date1, date2).updated_before(date3).find(:all,
  :include => :carts)

Обновление: суть named_scope s, конечно же, в повторном использовании условий. Вам решать, имеет ли смысл помещать набор условий в именованную область видимости или нет.

carts выполнит соединение, если вы добавили has_many: carts в свою модель Book . Как видите, не требуется много SQL. Даже кавычки и экранирование ввода можно оставить Rails, при этом все еще используя литералы SQL для обработки операторов > = и <= .

Пойдем немного дальше, вы можно сделать это еще яснее:

class Book < AciveRecord::Base
  # Somewhere in your Book model:
  named_scope :created_between, lambda { |start_date, end_date|
    { :conditions => { :created_at => start_date..end_date } }
  }
  named_scope :updated_before, lambda { |date|
    { :conditions => ["updated_at <= ?", date] }
  }
  # ...
end

Book.created_between(date1, date2).updated_before(date3).find(:all,
  :include => :carts)

Обновление: суть named_scope s, конечно же, в повторном использовании условий. Вам решать, имеет ли смысл помещать набор условий в именованную область видимости или нет.

carts выполнит соединение, если вы добавили has_many: carts в свою модель Book . Как видите, не требуется много SQL. Даже кавычки и экранирование ввода можно оставить Rails, при этом все еще используя литералы SQL для обработки операторов > = и <= .

Пойдем немного дальше, вы можно сделать это еще яснее:

class Book < AciveRecord::Base
  # Somewhere in your Book model:
  named_scope :created_between, lambda { |start_date, end_date|
    { :conditions => { :created_at => start_date..end_date } }
  }
  named_scope :updated_before, lambda { |date|
    { :conditions => ["updated_at <= ?", date] }
  }
  # ...
end

Book.created_between(date1, date2).updated_before(date3).find(:all,
  :include => :carts)

Обновление: суть named_scope s, конечно же, в повторном использовании условий. Вам решать, имеет ли смысл помещать набор условий в именованную область видимости или нет.

все еще используя литералы SQL для обработки операторов > = и <= .

Если пойти немного дальше, вы можете сделать это еще яснее:

class Book < AciveRecord::Base
  # Somewhere in your Book model:
  named_scope :created_between, lambda { |start_date, end_date|
    { :conditions => { :created_at => start_date..end_date } }
  }
  named_scope :updated_before, lambda { |date|
    { :conditions => ["updated_at <= ?", date] }
  }
  # ...
end

Book.created_between(date1, date2).updated_before(date3).find(:all,
  :include => :carts)

Обновление: суть named_scope s, конечно же, повторное использование условий. Вам решать, имеет ли смысл помещать набор условий в именованную область видимости или нет.

все еще используя литералы SQL для обработки операторов > = и <= .

Если пойти немного дальше, вы можете сделать это еще яснее:

class Book < AciveRecord::Base
  # Somewhere in your Book model:
  named_scope :created_between, lambda { |start_date, end_date|
    { :conditions => { :created_at => start_date..end_date } }
  }
  named_scope :updated_before, lambda { |date|
    { :conditions => ["updated_at <= ?", date] }
  }
  # ...
end

Book.created_between(date1, date2).updated_before(date3).find(:all,
  :include => :carts)

Обновление: суть named_scope s, конечно же, повторное использование условий. Вам решать, имеет ли смысл помещать набор условий в именованную область видимости или нет.

13
ответ дан 6 December 2019 в 12:53
поделиться

Как molf говорит с помощью: include, .find () имеет преимущество в виде быстрой загрузки дочерних элементов. Кроме того, есть несколько плагинов, таких как разбиение на страницы, которые оборачивают функцию поиска. Вам нужно будет использовать .find () для использования плагинов.

Если у вас действительно сложный sql-запрос, помните, что .find () использует вашу точную строку параметров. Вы всегда можете ввести свой собственный sql-код:

: conditions => ["id in union (select * from table ...

] И не забывайте, что есть много необязательных параметров для .find ()

  • : условия - фрагмент SQL, например "administrator = 1", ["user_name =?", Username] или ["user_name =: user_name", {: user_name => user_name}]. См. Условия во вступлении.
  • : order - Фрагмент SQL, например «created_at DESC, name».
  • : group - Имя атрибута, по которому должен быть сгруппирован результат. Использует SQL-предложение GROUP BY.
  • : имеющий - В сочетании с + : group + это можно использовать для фильтрации записей, возвращаемых GROUP BY. Использует предложение HAVING SQL.
  • : limit - Целое число, определяющее предел количества строк, которые должны быть возвращены.
  • : offset - Целое число, определяющее смещение, от которого строки должны быть извлечены. Таким образом, в 5 он пропустит строки с 0 по 4.
  • : joins - Либо фрагмент SQL для дополнительных объединений, таких как «LEFT JOIN comments ON comments.post_id = id» (требуется редко), именованные ассоциации в той же форме, что и для параметр: include, который будет выполнять ВНУТРЕННЕЕ СОЕДИНЕНИЕ для связанной таблицы (таблиц) или массива, содержащего смесь как строк, так и именованных ассоциаций. Если значение является строкой, тогда записи будут возвращены только для чтения, поскольку они будут иметь атрибуты, не соответствующие столбцам таблицы. Передайте: readonly => false для отмены.
  • : include - Имена ассоциаций, которые должны быть загружены вместе. Названные символы относятся к уже определенным ассоциациям. См. Активную загрузку в разделе «Связи».
  • : select - По умолчанию это «*», как в «SELECT * FROM», но его можно изменить, если вы, например, хотите выполнить соединение, но не включать объединенные столбцы. Принимает строку с фрагментом SQL SELECT (например, «id, name»).
  • : from - По умолчанию это имя таблицы класса, но его можно изменить на другое имя таблицы (или даже имя представление базы данных).
  • : readonly - Отметьте возвращенные записи как доступные только для чтения, чтобы их нельзя было сохранить или обновить.
  • : lock - Фрагмент SQL, например «FOR UPDATE» или «LOCK IN SHARE MODE». : lock => true дает исключительную блокировку соединения по умолчанию, обычно «ДЛЯ ОБНОВЛЕНИЯ».

src: http: // api. rubyonrails.org/classes/ActiveRecord/Base.html#M002553[1230 impression

3
ответ дан 6 December 2019 в 12:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: