I am building a system for category search. At that time, the following errors are occurring in the current system.
Couldn't find all Post with 'id': (false, true) (found 1 results, but was looking for 2).
Controllers
def category
@category = params[:category_name]
@posts=Post.find(PostCategory.group(:post_id).pluck(:@category))
#↑The error point.
end
routes
get '/category/:category_name', to: 'pages#category'
Views
<li><a href="category/casual">casual</a></li>
<li><a href="category/natural">natural</a></li>
<li><a href="category/clean">clean</a></li>
<li><a href="category/rock">rock</a></li>
<li><a href="category/formal">formal</a></li>
<li><a href="category/street">street</a></li>
<li><a href="category/hip_hop">hip_hop</a></li>
<li><a href="category/sports">sports</a></li>
<li><a href="category/outdoors">outdoors</a></li>
<li><a href="category/surf">surf</a></li>
Relationship of models
belongs_to :post
has_one :post_category
accepts_nested_attributes_for :post_category
PostCategory table
create_table "post_categories", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "casual", default: false, null: false
t.boolean "natural", default: false, null: false
t.boolean "clean", default: false, null: false
t.boolean "rock", default: false, null: false
t.boolean "formal", default: false, null: false
t.boolean "street", default: false, null: false
t.boolean "hip_hop", default: false, null: false
t.boolean "sports", default: false, null: false
t.boolean "outdoors", default: false, null: false
t.boolean "surf", default: false, null: false
t.integer "post_id"
t.index ["post_id"], name: "index_post_categories_on_post_id"
end
Example.
I want to find a column where category_name params(casual)
and PostCategory column(casual)
are the same, and from there, find only the ones that are true, and retrieve all the records of Post
whose post_id
corresponds to PostCategory column(casual, only true)
and reflect them in the view.
Thank you.
First, there's a problem in your category
method where it says :@category
. That would probably need to say @category
(without the colon), so that the method body's second line reads:
@posts=Post.find(PostCategory.group(:post_id).pluck(@category))
^
That aside, it seems that you're trying to fetch all posts that belong to a certain category. What you're doing right now won't work because your query returns an array of booleans, and then you use booleans to look up posts. But you'd need ids to look up posts because you can't pass booleans to Post.find
.
Why not just do (not tested):
@posts = Post.find(PostCategory.where(@category => true).pluck(:post_id))
or, in a single query (not tested either):
@posts = Post.joins(:post_category).where("post_categories.#{@category}" => true)
But for that last one you may need to check the @category
variable against a whitelist to avoid injections. EDIT: As Max suggests in the comments, you may want to change the where clause to where( post_categories: { @category => true })
to avoid injections.