ajax не отвечает - create.js.erb

Я работаю с гемом jquery-file-upload-rails для загрузки нескольких изображений с предварительным просмотром в моей форме. Загрузка файла работает, но часть с новыми фотографиями отображается только после обновления браузера! Может быть, кто-то может увидеть, что не так.

Я вызываю загрузчик файлов для загрузки фотоизображений на странице редактирования проекта:

= f.fields_for :photos, Photo.new do |ff|
  = ff.file_field :img_file, multiple: true, name: "project[photos_attributes][][img_file]", id: 'new_photo'

Фотоконтроллер:

  def create
    @project = Project.find(params[:project_id])
    @photo = @project.photos.create(params[:photo].permit(:img_file))
    respond_to do |format|
      format.js
      format.html
    end
  end

photos.js.coffee, чтобы заставить работать камень jquery-file-uploader-rails:

jQuery ->
  $('#new_photo').fileupload
    dataType: 'script'

create.js.erb

$('#photos').html("<%= j render(@photo) %>");

_photo.html.haml

.photo
  - @project.photos.each do |photo|
    = image_tag photo.img_file.thumb
    = link_to 'Remove', photo, data: { confirm: "Are you sure?" }, method: :delete

Так что я могу загружать фотографии. Но мой аякс не работает, даже если я ставлю только предупреждение ("помощь"); в моем create.js.erb он не отвечает. Что я делаю неправильно? Спасибо заранее!

ОБНОВЛЕНИЕТекущая ситуация (с помощью Rich Peck):

Мои модели:

class Project < ActiveRecord::Base
  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos, allow_destroy: true
end

class Photo < ActiveRecord::Base
  belongs_to :project
  validates :img_file, presence: true
  mount_uploader :img_file, ImageUploader
end

Контролер проектов:

  def edit
    @project = Project.find(params[:id])
    @project.photos.build
  end

  def update
    @project = Project.find(params[:id])
    @project.update(project_params)
  end

params.require(:project).permit(photos_attributes: [:img_file])

/ Проекты / редактировать

  = form_for @project do |f|
    = f.fields_for :photos do |p|
      = p.file_field :img_file, multiple: true, id: 'new_photo'       
  #photos
    = render 'photos/photo'

/ Фото / _photo

.photo
  = image_tag photo.img_file.thumb if photo.img_file?
  = link_to 'Remove', photo, data: { confirm: "Are you sure?" }, method: :delete

/photos/create.js.erb

$('#photos').html("<%= j render(@photo) %>");

/javascripts/photos.js.coffee

jQuery ->
  $('#new_photo').fileupload
    dataType: 'script'

3 ответа

Для загрузки файла AJAX для работы в jquery-file-upload драгоценный камень

ты должен добавить :html => { :multipart => true} к вашей форме

<%= form_for Upload.new, :html => { :multipart => true} } do |f| %> ... <%end%>

Пожалуйста, ознакомьтесь с примером формы jQuery-File-Upload

Несколько вопросов.

#app/controllers/projects_controller.rb
class ProjectsController < ApplicationController
   respond_to :js, :html

   def new
      @project = Project.new
      @project.photos.build #-> this will replace Photo.new in fields_for
   end

   def create
      @project = Project.new project_params
      @project.save
      respond_with @project
   end

   private

   def project_params
      params.require(:project).permit(photos_attributes: [:img_file])
   end
end 

#app/views/projects/new.haml
= form_for @project do |f|
    = f.fields_for :photos do |ff|
       = ff.file_field :img_file, multiple: true, id: 'new_photo'

При использовании вложенных атрибутов вы никогда не должны объявлять name атрибут ваших вложенных полей. Мало того, что это против соглашения, но это также оставляет дверь открытой для взлома и ошибок.

Если вы используете nested attributes нужно пройти мимо @project сначала объект, что означает, что форма будет либо передавать projects#update или же projects#create... не photos#create что у тебя сейчас.

Я также настоятельно рекомендую использовать respondersдрагоценный камень, он очистит ваш код в массовом порядке.

-

Если вы хотите создать новый Photo объект самостоятельно, вы хотите использовать следующее:

#config/routes.rb
resources :projects do
   resources :photos #-> url.com/projects/:project_id/photos/new
end

#app/controllers/photos_controller.rb
class PhotosController < ApplicationController
   respond_to :js, :html

   def new
      @project = Project.find params[:project_id]
      @photo   = @project.photos.new
   end

   def create
      @project = Project.find params[:project_id]
      @photo   = @project.photos.new photo_params
      @photo.save
      respond_with @photo
   end

   private

   def photo_params
      params.require(:photo).permit(:img_file)
   end
end

#app/views/photos/new.haml
= form_for @photo do |f|
   = f.file_field :img_field

Ваш код JS неверен...

$('#photos').html("<%= j render(@photo) %>");

По умолчанию Rails обрабатывает "коллекции", вызывая _[collection_singular_name].html.erb - в твоем случае _photo.html.erb, Он просматривает коллекцию, чтобы показать это каждый раз. Чтобы исправить это, просто удалите петлю из вашего частичного:

#app/views/photos/_photo.html.erb
= image_tag photo.img_file.thumb
= link_to 'Remove', photo, data: { confirm: "Are you sure?" }, method: :delete

Решение

Решите, создаете ли вы project или же photo,

Если вы создаете photo, вы должны использовать отдельный photos контроллер (обрисован в общих чертах выше). Если вы создаете новый проект, вы должны использовать nested attributes должным образом. Мы использовали JQuery-File-Upload Несколько раз до этого (вы можете бесплатно зарегистрироваться только в тестовом приложении):

Ваша структура кода выглядит хорошо, только контроллер и JS, которые имеют проблемы.


Обновить

Чтобы добавить новое фото через проект edit Форма, просто используйте следующее:

#app/controllers/projects_controller.rb
class ProjectsController < ApplicationController
   def edit
      @project = Project.find params[:id]
      @project.photos.build
   end

   def update
      @project = Project.find params[:id]
      @project.update project_params
   end

   private

   def project_params
      params.require(:project).permit(photos_attributes: [:img_file])
   end
end

#app/views/projects/edit.html.erb
<%= form_for @project do |f| %>
   <%= f.fields_for :photos do |p| %>
      <%= p.file_field :img_file %>
   <% end %>
   <%= f.submit %>
<% end %>

Использование

$('#photos').html(escape_javascript("<%= j render(@photo) %>"));

см. http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html

Другие вопросы по тегам