Не удается сохранить атрибуты изображения с помощью скрепки в рельсах 4
В моем приложении Rails 4 есть две связанные модели: product.rb
и image.rb
. Модель Image позволяет прикреплять файлы, используя драгоценный камень Paperclip.
Изображения belong_to
a Продукт и продукт has_many
Изображения.
Я хотел бы использовать представление Product new
для создания и прикрепления изображения при создании продукта. Каждый раз, когда я пытаюсь, параметры, связанные с изображением Paperclip, не сохраняются и заканчиваются nil
.
Вот модели:
Product.rb
class Product < ActiveRecord::Base
validates :name, :part_number, presence: true
has_many :images, dependent: :destroy
belongs_to :category
accepts_nested_attributes_for :images, allow_destroy: true
end
Image.rb
class Image < ActiveRecord::Base
belongs_to :product
has_attached_file :image
end
Просматривая прошлые вопросы о переполнении стека, я нашел некоторые соответствующие вопросы и ответы, но ни один из них, похоже, не помогает моей конкретной ситуации. Пока я могу представить файл с правильными атрибутами, но он не сохраняет их в базе данных.
ProductsController#create
def create
@product = Product.new(product_params)
end
def product_params
params.require(:product).permit(:name,
:category_id,
:part_number,
images_attributes: [:image])
end
ProductsController#new
def new
@product = Product.new
@categories = # irrelevant to question
end
products/new.html.haml
= form_for @product, :html =>
= f.label :name
= f.text_field :name
= f.label :part_number
= f.text_field :part_number
= f.label :category_id
= f.select :category_id, @ca
= f.fields_for :image do |ff|
= ff.label :image
= ff.file_field :image
= f.submit('Create Product')
Глядя на параметры, я могу сказать, что передаются правильные атрибуты:
Параметры примера:
{"utf8"=>"✓",
"authenticity_token"=>"jGNy/TasHzP0EcWDFzZ3XH5/fpxb6vD+ncQ2PZSQ3/I=",
"product"=>{"name"=>"bar",
"part_number"=>"foo",
"category_id"=>"30",
"image"=>{
"image"=>#<ActionDispatch::Http::UploadedFile:0x007fc82f58e0e0
@tempfile=#<Tempfile:/var/folders/04/23d9grkj5fv3wkj2t8858kx40000gn/T/RackMultipart20131029-64949-1ldkz4g>,
@original_filename="FPE230_b.jpg",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"product[image][image]\"; filename=\"FPE230_b.jpg\"\r\nContent-Type: image/jpeg\r\n">}},
"commit"=>"Create Product"}
Однако изображение фактически не сохраняется в базе данных. Как я могу это исправить?
ИЗМЕНИТЬ
Внимательно изучая журналы, я вижу, что получаю ошибку "unpermitted parameters: image". Это даже после добавления images_attributes: [:image]
к моему методу product_params
.
Ответы
Ответ 1
Мне удалось настроить настройки, похожие на ваши, со следующими изменениями:
В ProductsController#create
вместо создания изображения отдельно, пусть вложенные атрибуты обрабатывают его и просто делают:
@product = Product.new(product_params)
И разрешите вложенные параметры (я понял image_attributes: [:image]
из этот вопрос):
def product_params
params.require(:product).permit(:name, :part_number, images_attributes: [:image])
end
Вот как выглядят мои параметры в журналах для запроса create
:
{
"utf8"=>"✓",
"authenticity_token"=>"7EsPTNXu127itgp4fbohu672/L4XnSwLEkrqUGec3pY=",
"product"=>{
"name"=>"whatever",
"part_number"=>"12345",
"images_attributes"=>{
"0"=>{
"image"=>#<ActionDispatch::Http::UploadedFile:0x007feb0c183b08
@tempfile=#<Tempfile:/var/folders/6k/16k80dds0ddd6mhvs5zryh3r0000gn/T/RackMultipart20131031-51205-emaijs>,
@original_filename="some-image.png",
@content_type="image/png",
@headers="Content-Disposition: form-data; name=\"product[images_attributes][0][image]\"; filename=\"ponysay.png\"\r\nContent-Type: image/png\r\n">
}
}
},
"commit"=>"Create"}
И я вижу вставку в products
и вставку в images
.
Если это не сработает, можете ли вы разместить свою ProductsController#new
и новую форму продукта?
ИЗМЕНИТЬ ПОСЛЕ ВАШЕГО ИЗМЕНЕНИЯ:
У меня есть 3 разных объекта в app/views/products/new.html.erb
и ProductsController#new
, которые могут повлиять на ваши результаты:
-
В form_for
у меня есть multipart: true
, как в документация paperclip:
<%= form_for @product, :url => products_path, :html => { :multipart => true } do |f| %>
-
Поскольку Product
has_many :images
, в моей форме у меня есть fields_for :images
вместо fields_for :image
:
<%= f.fields_for :images do |i| %>
<%= i.file_field :image %>
<% end %>
-
Этот fields_for
не показывает ничего на странице, если только в ProductsController#new
я не создаю образ; ваш Product.new
делает это случайно?
def new
@product = Product.new
@product.images.build
end
Есть ли какие-то особые причины для этих различий? Работает ли ваш код, если вы меняете его в соответствии с моим?