- PVSM.RU - https://www.pvsm.ru -
Если у вас когда либо возникала чудная ситуация, когда вы прописали ассоциации для моделей (has_one и belongs_to), accepted_nested_attributes, но хелпер fields_for не показывает форму то это пост поожет вам раз и навсегда избавится от этого «глюка». Заранее предупреждаю, что пост сугубо для rails разработчиков, и ни для кого никому, кроме как rails разработчикам интересен не будет!
Итак, допустим у нас есть следующие модели:
class Company < ActiveRecord::Base
belongs_to :location
has_one :user
accepts_nested_attributes_for :user
accepts_nested_attrbiutes_for :location
end
class User < ActiveRecord::Base
belongs_to :company
end
class Location < ActiveRecord::Base
has_one :company
end
Нам нужна форма компании с вложенными ресурсами user и location. На первый взгляд может показаться что кода:
form_for :company do |f|
f.text_field :name
f.fields_for :user, f.object.user_or_build do |fu|
fu.text_field :name
end
f.fields_for :location, f.object.location_or_build do |fl|
fl.text_field :address
end
end
будет достаточно, чтобы показать желаемую форму. Однако это не так. Запустив приложение и открыв браузер вы увидете, что вместо ожидаемых 3-х полей на странице всего одно — это поле name для company (предполагается, что у нас есть проинициализированный объект как то так:
@company = Company.new
).
Проблема кроется в том, что мы не проинициализировали ассоциированные объекты user и location для @company:
@company.build_location # то же что и @company.location = Location.new
@company.build_user # то же что и @company.user = User.new
Если эти условия выполнить до выполнения хелперов fields_for, то форма будет выглядеть как мы и ожидали. Однако писать каждый раз такой код в контроллерах как-то несерьезно, ведь контроллеры должны быть чистыми!
Избежать данную проблему можно с помощью этого гема [1], который носит немного неуклюжие название — get_or_build.
Добавляем в Gemfile строку:
gem 'get_ot_build'
Устанавливаем gems: bundle install, перезапускаем приложение и рефакторим код с хелперами fields_for следующим образом:
form_for :company do |f|
f.fields_for :user, :build_association => true do |fu|
fu.text_field :name
end
f.fields_for :user, :build_association => true do |fl|
fl.text_field :address
end
end
После этого код инициализации объектов ассоциаций user и location можно удалить из контроллеров, шаблонов и хелперов (еще где-то, где он есть ;) и уже не нужен).
Буду очень признателен за критику и коментарии, также приветствуются добровольцы для развития гема. Спасибо за внимание!
Автор: ka8725
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/rails/15364
Ссылки в тексте:
[1] гема: https://github.com/ka8725/get_or_build
Нажмите здесь для печати.