Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МУ_по созданию ИС с помощью RoR_2018.docx
Скачиваний:
9
Добавлен:
17.06.2023
Размер:
12.5 Mб
Скачать

11 Элементы сложной обработки данных

Динамические средства поиска. Для поиска информации во многих языках программирования и платформах необходимо составлять SQL-запросы. Active Record делает это за нас, используя динамические возможности языка Ruby.

Если вызывается метод класса модели, имя которого начинается с find_by_(), find_last_by_() или find_all_by_(), Active Record преобразует его в поисковую функцию, используя оставшуюся часть имени метода как определитель выбранного столбца. Например:

order = Order.find_by_name("Dave Thomas"),

где Order – название таблицы (модели), find_by_() – приисковой метод, name – название столбца, Dave Thomas – одно из значений столбца. в действительности преобразуется Active Record в следующий код:

order = Order.where(name: "Dave Thomas").first

Точно так же вызовы find_all_by_xxx и find_last_by_xxx подставляют, соответственно, вызовы all() и last() вместо подразумеваемого вызова first().

Active Record способен также создавать поисковые функции, работающие с несколькими столбцами. Например:

user = User.find_by_name_and_password(name, pw).

SQL и Active Record. Чтобы проиллюстрировать работу Active Record с SQL, передадим простую строку вызову метода where(), который соответствует SQL-условию where. where. Например, чтобы был возвращен перечень всех заказов, сделанных человеком по имени Dave со способом оплаты 'po', можно воспользоваться следующей строкой:

pos = Order.where("name = 'Dave' and pay_type = 'po'").

Один из способов установки заменяемых элементов заключается в расстановке в коде SQL одного или нескольких вопросительных знаков. Первый вопросительный знак будет заменен вторым элементом массива, второй — третьим, и т. д. Например,

name = params[:name]

pos = Order.where(["name = ? and pay_type = 'po'", name])

Выделение групп из возвращаемых записей. Методы, поддерживаемые реляционным объектом класса ActiveRecord::Relation, начиная с first() и all():

Метод order() позволяет нам указать критерии, которые обычно добавляются после ключевых слов order by.

Метод limit() позволяет ограничивать количество возвращаемых строк.

Метод offset() позволяет указать смещение первой строки в наборе возвращаемых результатов.

Метод select() позволяет ограничить возвращаемые значения в том случае, если требуется вполне определенный набор данных, имеющихся в таблице.

Метод joins() позволяет определить перечень дополнительных таблиц, присоединяемых к таблице, используемой по умолчанию.

Метод readonly() заставляет ActiveRecord::Resource вернуть объекты Active Record, которые не могут быть опять сохранены в базе данных.

Метод group() добавляет оператор group by к SQL-коду, сгенерированному методом find().

Метод lock() допускает в качестве необязательного аргумента строку, которая должна быть фрагментом кода SQL, имеющим синтаксис используемой базы данных, которым определяется вид блокировки.

Написание собственного кода SQL. Каждый из рассмотренных методов вносит свой вклад в конструирование полной строки SQL-запроса. А метод find_by_sql() позволяет вашему приложению получить полный контроль над этим процессом. Он допускает использование одного аргумента, содержащего SQL-инструкцию select (или содержащего массив, состоящий из кода SQL и значений заменяемых элементов, как для метода find()), и возвращает (возможно, пустой) массив объектов модели из результирующего множества.

orders = Order.find_by_sql("select name, pay_type from orders")

first = orders[0]

p first.attributes

p first.attribute_names

p first.attribute_present?("address")

Метод find_by_sql() также может использоваться для создания объектов модели, содержащих данные, извлеченные из столбцов.

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

Order.find_by_sql(["select * from orders where amount > ?",

params[:amount]])

В прежние времена при работе с Rails специалисты часто прибегали к использованию метода find_by_sql(). Сейчас те аргументы, которые были добавлены к основному методу find(), позволяют обойтись без обращения к этому низкоуровневому методу.

Обновление существующих строк. Если происходит обновление существующей строки, для сопоставления с объектом, находящимся в памяти, Active Record воспользуется ее же столбцом первичного ключа. Свойства, содержащиеся в объекте Active Record, определяют обновляемые столбцы: столбец базы данных будет обновлен только в том случае, если его значение было изменено. В следующем примере в таблице базы данных могут быть обновлены все значения строки заказа 123:

table:

order = Order.find(123)

order.name = "Fred"

order.save

Если объект Active Record содержит только такие свойства, как id, name и paytype, поэтому при его сохранении могут быть обновлены только соответствующие им столбцы:

orders = Order.find_by_sql("select id, name, pay_type from orders where id=123")

first = orders[0]

first.name = "Wilma"

first.save

Имейте в виду: если вы намерены сохранить строку, извлеченную с помощью метода find_by_sql(), нужно обязательно задействовать столбец id.

Удаление строк. Active Record поддерживает два способа удаления строк:

  1. delete() и delete_all()

  2. 2) применение различных методов destroy

Метод delete() получает одиночный идентификатор (id) или массив идентификаторов и удаляет соответствующую строку или строки в используемой базе данных. Метод delete_all() удаляет строки, соответствующие заданным условиям. Принадлежащий экземпляру объекта метод destroy() удаляет из базы данных строку, соответствующую конкретному объекту модели. Затем содержимое модели «замораживается», предотвращая последующие изменения свойств.

Если нужно, чтобы база данных не противоречила бизнес-правилам, определенным в классах модели, лучше использовать методы destroy.