on the posts form errors it says 'User Must Exist'.
The correct parameters are being received including the user_id, but all the parameters are still rejected. I suspect its something to do with the array of hashes as they come from another controller but via a form.
So when I inspect the Post params it says:
<ActionController::Parameters {"email"=>"test@test.com", "user_id"=>"2", "items_bought"=>"[#<LineItem id: 3, product_id: 1, cart_id: 3, quantity: 1>, #<LineItem id: 4, product_id: 2, cart_id: 3, quantity: 4>]"} permitted: false>
Simple_form_for @post
<%= simple_form_for @post, :url => user_posts_path do |f| %>
<%= f.error_notification %>
<ul>
<%= @post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<%end%>
</ul>
<%= f.input :email, :input_html => { value: "#{current_user.email}" } %>
<%= f.input :user_id, :as => :hidden, :input_html => { value: "#{current_user.id}" } %>
<%= f.input :items_bought, :as => :hidden, :input_html => { value: "#{current_cart.line_items.to_a}" } %>
<%= f.error :base %>
<%= f.button :submit %>
<% end %>
Posts controller
class PostsController < ApplicationController
def new
@user = current_user
@post = Post.new
end
def create
@user = current_user
@post = current_user.posts.build(params[:post_params])
if @post.save
render plain:
params[:post].inspect
else
render 'new'
end
end
private
def post_params
params.require(:post).permit(:email, :user_id, items_bought: [:LineItem_id [], :product_id[], :cart_id[], :quantity[]])
end
end
Post Model
class Post < ApplicationRecord
belongs_to :user, dependent: :destroy
end
any help would be greatly appreciated
You are not using your post_params
method, change this:
@post = current_user.posts.build(params[:post_params])
to this:
@post = current_user.posts.build(post_params)
EDIT: note that passing the user_id as a parameter is a security risk, someone can change the hidden field value. Use the current_user id instead of receiving the id from the form.
Actually, all the hidden info is retrieved from the current_user, you don't really need to use hidden fields since if you have access to the current_user you already have access to all that (id, cart items)
EDIT 2: if you want to have an array of hashes inside the :items_bought parameter, you need to use multiple hidden fields with specific names so it's parsed as hashes by rails.
Let's say you have this structure:
[
{
id: 1,
name: 'Foo',
some_attr: 'Lorem'
},
{
id: 2,
name: 'Bar',
some_attr: 'Impsum'
}
]
If you send that as parameters you need multiple hidden fields:
hidden_field_tag 'items_bought[1][id]', 1
hidden_field_tag 'items_bought[1][name]', 'Foo'
hidden_field_tag 'items_bought[1][some_attr]', 'Lorem'
hidden_field_tag 'items_bought[2][id]', 2
hidden_field_tag 'items_bought[2][name]', 'Bar'
hidden_field_tag 'items_bought[2][some_attr]', 'Impsum'
When submitted, params[:items_bought]
will be:
{
'1' => {
id: '1',
name: 'Foo',
some_attr: 'Lorem'
},
'2' => {
id: '2',
name: 'Bar',
some_attr: 'Impsum'
}
}
Note it's not the same, it's a hash of hashes and you have the ID if each hash as the key (that's the first part of the hidden field name items_bought[1]
and items_bought[2]
, and the ids are strings, not numbers.
You could also serialize the hash as a string:
hidden_field_tag :items_bougth, my_hash.to_json
and then on the controller do
param_hash = JSON.parse(params[:items_bought]
but I woudn't recommend this, it's a sign of something done more complex than it needs to be, you need to parse the parameters, use an extra library, etc.
Note you shouldn't do any of this with complex objects like LineItem as is, you talk about an array of hashes, an array of LineItems is not an array of hashes, you have to convert the objects to hashes first for both methods to work consistently.