rails g model Модель3 модель1:references модель2:references
Пример
rails g model GroupMembers user:references group:references
Модель.update_attribute :поле, значение
Модель.тouch :поле
user = User.find(1)
user.posts = [Post1, Post2, PostN]
Использования callback следует избегать (плохой стиль программирования).
Если при сохранении объекта в callback он тут же будет использован (например, его ID будет передан в качестве параметра в фоновую задачу), то вместо after_save для сохранения этого объекта лучше использовать after_commit, так как правильный ID сохраняемого объекта может быть и не получен до того, как коммит завершится.
При использовании методов, создающих Relation SQL запрос, выполняется только при использовании методов, требующих получения информации из результирующих записей запроса (ленивая загрузка). Realtion позволяет вызывать цепочку методов, конструируя таким образом SQL запрос. С результирующими записями, полученными в виде Relation необходимо работать как с массивами (то есть для обращения к одной записи использовать либо индекс элемента массива, либо методы типа first|last).
Scope определяются в модели (по сути это определение методов класса модели) и позволяют создавать пользовательские методы для Relation, которые могут вызваться по цепочке.
scope :important, -> { where(:is_important => true) }.
Результат вызова Scope это Relation объект.
Для объектов Scope доступны методы модели, то есть сделав метод модели, к примеру – для фильтрации записей, этот метод можно по цепочке вызвать для Relation объекта
Модель.scope1.scope2.метод_модели
Для использования в определении scope созданной в другой модели scope используется merge:
scope :имя1, -> { joins(:device).merge(Device.имя2) }
Модель.where(nil) или Модель.all создают объект Relation, из которого можно строить сложные запросы, взывая методы по цепочке
my_scope = Модель.all
my_scope = my_scope.where(type: :tag)
my_scope = my_scope.limit(10).to_a
или для создания новой записи
my_scope = Модель.all
@ресурс = my_scope.build
@ресурс.attributes = my_params
@ресурс.save
Concerns (концерны) позволяют вынести одинаковый код из разных моделей или контроллеров в один concern файл. То есть в концерны выносится код, наделяющий общими свойствами модели или контроллеры, например, комментируемость модели (концерн Taggable), тегируемость модели), общие методы контроллеров (например, одинаковые фильтры при авторизации). С помощью концернов можно 1) определить общие для нескольких моделей связи, валидаторы, scopes, коллбэки (см. комментарий 1 ниже); 2) определить общие для нескольких моделей методы экземпляров (см. комментарий 2 ниже); 3) определить общие для нескольких моделей связи и (см. комментарий 3 ниже);
Файлы с Concern помещаются в подпапку concerns папки модели или контроллера.
В класс модели добавить
include Концерн
В файле с концерном
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable # 2 метод будет выполнены в контексте класса модели
end
def метод # 3 методы этого модуля будут методами экземпляров моделей
…
end
module ClassMethods # 1 методы этого модуля будут методами классов моделей
def метод
…
end
end
end