I want to use shrine gem in nested form, But happened
Unpermitted parameter: :photos_attributes
How to solve it? I tried some ways, that
def blog_form_params
params.require(:blog_form).permit(:title , :content ).merge!(user_id: current_user.id , :photos_attributes =>[:image, :id ,:destroy ])
end
and
def blog_form_params
params.require(:blog_form).permit(:title , :content ).merge!(user_id: current_user.id , photos_attributes: {:image, :id ,:destroy })
end
So on, but I can't solve it what is a matter of this error? Please tell me how to solve it
Strong Parameters
def blog_form_params
params.require(:blog_form).permit(:title , :content ).merge!(user_id:
current_user.id ,
photos_attributes: [:image, :id ,:destroy ])
end
BlogForm.rb
class BlogForm
include ActiveModel::Model
attr_accessor :title, :content, :user_id , :photos
def blog_builder
@user = User.find(user_id)
@blogs = @user.blogs.create(title: title , content: content )
return @blogs
end
concerning :PhotosBuilder do
attr_reader :photos_attributes
def photos
@blogs = blog_builder
@photos ||= @blogs.photos.new
end
def photos_attributes=(attributes)
@blogs = blog_builder
@photos ||= @blogs.photos.new(attributes)
end
end
def build_association
@user.photos << @photos if @photos != nil
end
def save
return false if invalid?
blog_builder
@blogs.save
@photos.save if @photos != nil
build_association
end
end
Send parameters
{"authenticity_token"=>"qDssddHt4EhfFWN33SPMk2F5fcvPToh143hrwilw0p98HK2RMEwdKDF7QsGYiSQ7AQHN02lpdBaCbSAed80Swg==",
"blog_form"=>{"title"=>"", "content"=>"sample", "photos_attributes"=>
{"image"=>#<ActionDispatch::Http::UploadedFile:0x00007f92408f07a8 @
tempfile=#<Tempfile:/tmp/RackMultipart20200406-4102-1x3utj1.png>,
@original_filename="p8-1.png", @content_type="image/png",
@headers="Content-Disposition: form-data;
name=\"blog_form[photos_attributes][image]\"; filename=\"p8-
1.png\"\r\nContent-Type: image/png\r\n">}}, "commit"=>"create",
"user_id"=>"2"}
blog.rb
class Blog < ApplicationRecord
belongs_to :user
has_many :photos
validates :title ,presence: true
validates :content ,presence: true
end
photo.rb
class Photo < ApplicationRecord
belongs_to :blog
belongs_to :user
include ImageUploader[:image]
end
uploader.rb
class ImageUploader < Shrine
end
shrine.rb
require "shrine/storage/file_system"
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"), # temporary
store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store"), # permanent
}
Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data
blogs_controller
def new
@blog_form = BlogForm.new
end
def create
@blog_form = BlogForm.new(blog_form_params)
if @blog_form.save
redirect_to user_blogs_path
else
#False action
end
end
def blog_form_params
params.require(:blog_form).permit(:title , :content, photos_attributes:
[:image] ).merge!(user_id: current_user.id)
end
I could solve this problem, Instead, I can't merge user_id Then happened ActiveRecord::RecordNotFound (Couldn't find User without an ID):
def blog_builder
@user = User.find(user_id)#Here is a new problem
@blogs = @user.blogs.create(title: title , content: content )
return @blogs
end
Maybe I could send params
(byebug) blog_form_params
<ActionController::Parameters {"title"=>"", "content"=>"sample",
"photos_attributes"=><ActionController::Parameters {"image"=>#
<ActionDispatch::Http::UploadedFile:0x00007f9240bc77b0 @tempfile=#
<Tempfile:/tmp/RackMultipart20200406-4102-rc9eo6.png>,
@original_filename="p8-1.png", @content_type="image/png",
@headers="Content-Disposition: form-data;
name=\"blog_form[photos_attributes][image]\"; filename=\"p8-
1.png\"\r\nContent-Type: image/png\r\n">} permitted: true>, "user_id"=>2}
permitted: true>
So error is attriubute to form object
I uploaded blog_form.rb
def blog_builder
@user = User.find(params[:user_id])#previously User.find(user_id)
@blogs = @user.blogs.create(title: title , content: content )
return @blogs
end
Doesn't work it, I got to (byebug) params[:user_id] *** NameError Exception: undefined local variable or method `params' for #
nil
I changed user_id instead of params[:user_id] So that
(byebug) @blog_form.user_id=params[:user_id]
NoMethodError Exception: undefined method `user_id=' for nil:NilClass
nil
Create
def create
@blog_form = BlogForm.new(blog_form_params)
@blog_form.user_id=params[:user_id]
if @blog_form.save
Blog_form
def blog_builder
@user = User.find(user_id)
@blogs = @user.blogs.create(title: title , content: content )
return @blogs
end
blog_form_params
(byebug) blog_form_params
<ActionController::Parameters {"title"=>"title", "content"=>"sample",
"photos_attributes"=><ActionController::Parameters {"image"=>#
<ActionDispatch::Http::UploadedFile:0x00007f80f5209680 @tempfile=#
<Tempfile:/tmp/RackMultipart20200407-10555-iewcks.png>,
@original_filename="p8-1.png", @content_type="image/png",
@headers="Content-Disposition: form-data;
name=\"blog_form[photos_attributes][image]\"; filename=\"p8-
1.png\"\r\nContent-Type: image/png\r\n">} permitted: true>, "user_id"=>2}
permitted: true>
Somwhow I could sent an user_id, I appreciate Fernand, Amit Patel, I used hidden_field in view filed instead of merge method
that is because you put the photos_attributes in the merge portion instead as blog_form attribute
how about this:
params.require(:blog_form).permit(:title , :content, :photos_attributes =>[:image, :id, :destroy] )
then update blogs_controller:
def create
@blog_form = BlogForm.new(blog_form_params)
@blog_form.user_id=params[:user_id]
...
then in BlogForm.rb:
def blog_builder
@user = User.find(user_id)
...