У меня есть 2 модели:
- Building →
has_many :building_views
- BuildingView →
belongs_to :building
Я могу создать BuildingView только для существующего Building (через edit / update Building). Атрибуты BuildingView: изображение (
image
) и заголовок(
title
).
Изображения загружаются через Carrierwave.
Предполагаемый workflow:
- Пользователь заходит на страницу редактирования Building
- Там есть file_field, который позволяет загружать сразу несколько файлов
- Он выбирает файлы и они загружаются с помощью гема
jquery-fileupload-rails
(создавая BuildingView для каждого изображения) - Сразу после загрузки они появляются на текущей странице (через ajax, без перезагрузки): превью и поле для редактирования заголовка BuildingView
C пунктами 1, 2 и 3 всё ок. Картинки грузятся, BuildingView создаются и после перезагрузки страницы они появляются на странице редактирования соответствующего Building с превью и полем редактирования заголовка (которое тоже успешно редактируется).
Проблема с пунктом номер 4: не получается вывести форму редактирования BuildingView через ajax. Я не могу понять как срендерить соответствующий партиал nested формы. Вот мои файлы:
controllers/admin/buildings_controller.rb
# other defs ...
def edit
@building = Building.find(params[:id])
end
def update
@building = Building.find(params[:id])
if @building.update_attributes(building_params)
flash[:success] = 'Woohoo!'
redirect_to admin_buildings_url
else
render :edit
end
end
# other defs ...
private
def building_params
params.require(:building).permit(:all_building_params,
building_views_attributes: [
:_destroy,
:id,
:building_id,
:image,
:title
])
end
views/admin/buildings/edit.html.haml
%h1 Edit building
= form_for [:admin, @building] do |f|
= render 'admin/buildings/form', f: f
.form-element-container
.form-element.b-form-labels
.form-element.b-form-fields
= f.submit 'Edit building'
= link_to t('admin.cancel'), :back
= form_for [:admin, BuildingView.new] do |f_bv|
= f_bv.hidden_field :building_id, value: @building.id
= f_bv.file_field :image, multiple: true, name: 'building_view[image]'
views/admin/buildings/_form.html.haml
// fields for Building...
#building_views
.form-element-container
.form-element
%h2 Building views
= f.fields_for :building_views do |bv_form|
= render 'admin/buildings/form_building_views', f: bv_form
views/admin/buildings/_form_building_views.html.haml
.form-element-container
.form-element.b-form-labels Image:
.form-element.b-form-fields= image_tag(f.object.image_url(:thumb)) if f.object.image
.form-element-container
.form-element.b-form-labels Title:
.form-element.b-form-fields= f.text_field :title
assets/javascript/admin/buildings.js.coffee
jQuery ->
$('#building_view_image').fileupload(
dataType: 'script'
)
controllers/admin/building_views_controller.rb
class Admin::BuildingViewsController < ApplicationController
def create
@building_view = BuildingView.create(building_view_params)
end
private
def building_view_params
params.require(:building_view).permit(:building_id, :image)
end
end
views/admin/building_views/create.js.haml
- if @building_view.new_record?
== alert('Oops!');
- else
== $('#building_views').append('#{j render('admin/buildings/form_building_views')}');
При отправке файлов я вижу в консоли ошибку:
ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x007ffaa52faad8>:0x007ffaa7393970>):
Мне нужно передать эту самую
f
:
j render( partial: 'admin/buildings/form_building_views', locals: { f: ??? } )
Как мне это сделать для партиала nested формы?