Загрузка полиморфных изображений Rails 4 с помощью Paperclip не работает для всех моделей

Новичок в Rails... и ТАК первый раз....

После пары руководств я решил попробовать создать систему управления событиями. Ничего похожего на амбиции, верно? События, художники и компании должны иметь возможность загружать одно изображение с помощью скрепки и вложенных форм. Я создал полиморфный класс Picture, и он отлично работает для загрузки/редактирования изображения для Artist, но когда я пытаюсь настроить его для Event, используя тот же самый код, я получаю сообщение об ошибке «Недопустимый параметр: picture_attributes». ... и ничего не сохраняется в БД.

Я искал/читал ответы в течение последних 3 дней, и я полностью застрял, поэтому я подумал, что могу добавить сюда свой код и посмотреть, сможет ли кто-нибудь определить, что мне может не хватать, и помочь мне понять, как получить это работать.

Вот фактический код ошибки из моей последней попытки загрузить изображение на событие:

Started PATCH "/events/12" for 127.0.0.1 at 2014-12-19 11:00:37 -0800
Processing by EventsController#update as HTML
Parameters: {"utf8"=>"✓",
 "authenticity_token"=>"AVkztH4s+t2oq/vjXloZeWxOW3pyD8sEorE3crMZr4Q=",
 "event"=>{"title"=>"Image Upload Test", "description"=>"Will this save to the db?",
 "picture_attributes"=>{
   "image"=>#<ActionDispatch::Http::UploadedFile:0x007fe7e9f6a3c8 @tempfile=#<Tempfile:/var/folders/kg/_bhw0x954nq1vdxsr4bwktvc0000gn/T/RackMultipart20141219-868-c377uk>, 
   @original_filename="RED_Tails_1.jpg", 
   @content_type="image/jpeg", 
   @headers="Content-Disposition: form-data; 
    name=\"event[picture_attributes][image]\"; 
    filename=\"RED_Tails_1.jpg\"\r\nContent-Type: image/jpeg\r\n">}, 
    "company_id"=>"1", 
    "venue_id"=>"1", 
    "production_artists_attributes"=>{
     "0"=>{"artist_id"=>"1", 
        "role"=>"German Commander", 
        "_destroy"=>"false", 
        "artist_type_id"=>"1", "id"=>"20"}}}, "button"=>"", "id"=>"12"}
Event Load (0.2ms)  SELECT  "events".* FROM "events"  WHERE "events"."id" = $1 LIMIT 1  [["id", 12]]
Unpermitted parameters: picture_attributes
(0.2ms)  BEGIN
ProductionArtist Load (0.2ms)  SELECT "production_artists".* FROM "production_artists"  WHERE
"production_artists"."event_id" = $1 AND "production_artists"."id" IN (20)  [["event_id", 12]]
SQL (1.3ms)  UPDATE "events" SET "company_id" = $1, "description" = $2, "title" = $3, "updated_at" = $4, "venue_id" = $5 WHERE "events"."id" = 12  [["company_id", 1], ["description", "Will this save to the db?"], ["title", "Image Upload Test"], ["updated_at", "2014-12-19 19:00:37.057793"], ["venue_id", 1]]
SQL (1.3ms)  UPDATE "production_artists" SET "artist_id" = $1, "role" = $2, "updated_at" = $3 WHERE "production_artists"."id" = 20  [["artist_id", 1], ["role", "German Commander"], ["updated_at", "2014-12-19 19:00:37.065119"]]
(90.1ms)  COMMIT
Redirected to http://localhost:3000/events/12
Completed 302 Found in 114ms (ActiveRecord: 93.3ms)

Вот мои модели:

class Event < ActiveRecord::Base
  has_one :picture, as: :imageable, dependent: :destroy
  accepts_nested_attributes_for :picture
end

class Artist < ActiveRecord::Base   
  has_one :picture, as: :imageable, dependent: :destroy
  accepts_nested_attributes_for :picture
end

class Picture < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
  has_attached_file :image, :styles => { :small => "180x180#", :thumb => "60x60#" }, 
                        path: ":rails_root/public/system/:attachment/:id/:style/:filename",
                        url: "/system/:attachment/:id/:style/:filename"
  validates_attachment  :image, :presence => true,
                    :content_type => { :content_type => %w(image/jpeg image/jpg image/png) },
                    :size => { :in => 0..1.megabytes }
end

Вот мои контроллеры:

class ArtistsController < ApplicationController
before_action :set_artist, only: [:show, :edit, :update, :destroy]

def index
 @artists = Artist.all
end

def show
end

def new
 @artist = Artist.new
 @artist.build_picture
end

def edit
end

def create
 @artist = Artist.new(artist_params)

respond_to do |format|
  if @artist.save
    format.html { redirect_to @artist, notice: 'Artist was successfully created.' }
    format.json { render :show, status: :created, location: @artist }
  else
    format.html { render :new }
    format.json { render json: @artist.errors, status: :unprocessable_entity }
  end
 end
end

def update
 respond_to do |format|
  if @artist.update(artist_params)
    format.html { redirect_to @artist, notice: 'Artist was successfully updated.' }
    format.json { render :show, status: :ok, location: @artist }
  else
    format.html { render :edit }
    format.json { render json: @artist.errors, status: :unprocessable_entity }
  end
 end
end

private
 def set_artist
  @artist = Artist.find(params[:id])
 end

 def artist_params
  params.require(:artist).permit(:first_name, :last_name,
    picture_attributes: [:image])
 end
end


class EventsController < ApplicationController
before_action :set_event, only: [:show, :edit, :update, :destroy]

def index
 @events = Event.all
end

def show
end

def new
 @event = Event.new
 @event.build_venue
 @venue = @event.build_venue
 @event.build_picture

end

def edit  
end

def create
 @event = Event.new(event_params)

respond_to do |format|
  if @event.save
    format.html { redirect_to @event, notice: 'Event was successfully created.' }
    format.json { render :show, status: :created, location: @event }
  else
    format.html { render :new }
    format.json { render json: @event.errors, status: :unprocessable_entity }
  end
 end
end

def update
respond_to do |format|
  if @event.update(event_params)
    format.html { redirect_to @event, notice: 'Event was successfully updated.' }
    format.json { render :show, status: :ok, location: @event }
  else
    format.html { render :edit }
    format.json { render json: @event.errors, status: :unprocessable_entity }
  end
 end
end

def destroy
 @event.destroy
  respond_to do |format|
   format.html { redirect_to events_url, notice: 'Event was successfully destroyed.' }
   format.json { head :no_content }
 end
end

private
 def set_event
  @event = Event.find(params[:id])
 end

 def event_params
  params.require(:event).permit(:title, :description, :image_url, :company_id, :venue_id,
    production_artists_attributes: [ :id, :event_id, :artist_id, :artist_type_id, :role, :_destroy,
      venues_attributes: [ :id, :name,
        picture_attributes: [:image]]] )
 end
end

Вот мои взгляды:

The Events form:
<%= form_for @event, html: { multipart: true } do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
<fieldset id="event-meta">
  <div class="form-group">
    <%= f.label :title %>
    <%= f.text_field :title, class: "form-control" %>
  </div>
  <div class="form-group">     
    <%= f.label :description %>
    <%= f.text_area :description, rows: 8, class: "form-control" %>
    <br />
  </div>
</fieldset>
<div class="form-group">
<p>Upload Picture</p>
  <%= f.fields_for :picture do |image_upload| %> 
    <%= image_upload.file_field :image, class: "form-control"  %>
  <% end %>
</div>
....

The Artist form:
<%= form_for @artist, html: { multipart: true } do |f| %>
   <%= render 'shared/error_messages', object: f.object %>
<div class="form-group">
   <%= f.label :first_name %>
   <%= f.text_field :first_name, class: "form-control"  %>
</div>
<div class="form-group">
   <%= f.label :last_name %>
   <%= f.text_field :last_name, class: "form-control"  %>
 </div>
<div class="form-group">
<p>Upload Picture</p>
  <%= f.fields_for :picture do |image_upload| %> 
    <%= image_upload.file_field :image, class: "form-control"  %>
  <% end %>
</div>

Итак... мне кажется, что все ДОЛЖНО работать... но это не так. Я, вероятно, упускаю что-то простое и надеюсь, что кто-то там может указать на это для меня.

FWIW... Прошлой ночью при поиске ответов у меня возникла мысль, что было бы лучше создать полиморфную модель профиля и прикрепить все изображения к тем, у которых есть отношение has_one, но даже если это так... Мне бы очень хотелось, чтобы некоторые помогите выяснить, почему я не могу заставить это работать сейчас, чтобы я мог узнать, что искать в будущем. Я совершенно сбит с толку.


person Jailyard90Grad    schedule 19.12.2014    source источник


Ответы (2)


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

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

Итак, я изменил это:

def event_params
 params.require(:event).permit(:title, :description, :image_url, :company_id, :venue_id,
  production_artists_attributes: [ :id, :event_id, :artist_id, :artist_type_id, :role, :_destroy,
  venues_attributes: [ :id, :name,
    picture_attributes: [:image]]] )
end 

к этому:

def event_params
 params.require(:event).permit(:title, :description, :image_url, :company_id, :venue_id,
  production_artists_attributes: [:id, :event_id, :artist_id, :artist_type_id, :role, :_destroy],
   venues_attributes: [:id, :name],
    picture_attributes: [:image])
end

и все работало как шарм.

person Jailyard90Grad    schedule 07.01.2015

Попробуйте обновить метод event_params следующим образом:

def event_params
  params.require(:event).permit(:title, :description, :image_url, :company_id, :venue_id,
  production_artists_attributes: [ :id, :event_id, :artist_id, :artist_type_id, :role,    :_destroy,
   venues_attributes: [ :id, :name,
    imageable_attributes: [:image]]] )
end

Дело здесь в том, что вы устанавливаете параметр as для отношения has_one равным imageable, и, вероятно, вам придется сделать что-то подобное для представления в полях для и на модели:

accepts_nested_attributes_for :imageable

<%= f.fields_for :imageable do |image_upload| %> 
  <%= image_upload.file_field :image, class: "form-control"  %>
<% end %>

Дайте мне знать, как это происходит.

person kurenn    schedule 21.12.2014
comment
Спасибо за ответ. Пробовал это. Теперь я получаю сообщение об ошибке «Неразрешенные параметры: изображение», и снова ничего не видит в БД. - person Jailyard90Grad; 21.12.2014
comment
Вы добавили правильное имя для imageable_attributes в методе event_params? - person kurenn; 22.12.2014
comment
Да, я сделал это изменение. Я действительно в растерянности. - person Jailyard90Grad; 22.12.2014
comment
Я перезапустил сервер, но он все равно не работает. Я только учусь пользоваться консолью, так что особо ничего с ней не делал, нет. - person Jailyard90Grad; 26.12.2014