Rails:Couldn't find all Post with 'id': (false, true) (found 1 results, but was looking for 2)
Rails:Couldn't find all Post with 'id': (false, true) (found 1 results, but was looking for 2)
我正在构建一个类别搜索系统。
当时,当前系统出现以下错误。
Couldn't find all Post with 'id': (false, true) (found 1 results, but was looking for 2).
控制器
def category
@category = params[:category_name]
@posts=Post.find(PostCategory.group(:post_id).pluck(:@category))
#↑The error point.
end
路线
get '/category/:category_name', to: 'pages#category'
观看次数
<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>
模型关系
belongs_to :post
has_one :post_category
accepts_nested_attributes_for :post_category
帖子类别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
我想做什么
例子。
我想找到 category_name params(casual)
和 PostCategory column(casual)
相同的列,然后从那里只找到为真的那些,并检索 Post
的所有记录 post_id
对应于 PostCategory column(casual, only true)
并在视图中反映它们。
谢谢。
首先,您的 category
方法存在问题,其中显示 :@category
。这可能需要说 @category
(没有冒号),以便方法主体的第二行显示为:
@posts=Post.find(PostCategory.group(:post_id).pluck(@category))
^
除此之外,您似乎正在尝试获取属于特定类别的所有帖子。你现在正在做的事情是行不通的,因为你查询 returns 一个布尔值数组,然后你使用布尔值来查找帖子。但是你需要 ID 来查找帖子,因为你不能将布尔值传递给 Post.find
.
为什么不直接做(未测试):
@posts = Post.find(PostCategory.where(@category => true).pluck(:post_id))
或者,在单个查询中(也未测试):
@posts = Post.joins(:post_category).where("post_categories.#{@category}" => true)
但是对于最后一个,您可能需要根据白名单检查 @category
变量以避免注入。编辑:正如 Max 在评论中所建议的那样,您可能希望将 where 子句更改为 where( post_categories: { @category => true })
以避免注入。
不需要修改数据库来添加类别的更好解决方案是设置更合理的规范化 table / 加入 table 设置:
# rails g model category name:string:uniq
class Category < ApplicationRecord
has_many :categorizations
has_many :posts, through: :categorizations
validates :name,
uniqueness: true,
presence: true
end
# rails g model categorization post:belongs_to category:belongs_to
class Categorization < ApplicationRecord
belongs_to :category
belongs_to :post
validates :post_id,
uniqueness: { scope: :category_id }
end
class Post < ApplicationRecord
has_many :categorizations
has_many :categories, through: :categorizations
end
处理这个问题的 Rails 要么在 categories#show 动作上处理(或使用嵌套路由):
resources :categories
class CategoriesController < ApplicationController
def show
@category = Category.find_by!(name: params[:id])
@posts = @category.posts
end
end
这当然意味着您有某种适当的设置,以确保类别的名称可以在 URL 的路径中使用。像 FriendlyID 这样的宝石是你的朋友。
@posts=Post.find(PostCategory.group(:post_id).pluck(:category))
我正在构建一个类别搜索系统。 当时,当前系统出现以下错误。
Couldn't find all Post with 'id': (false, true) (found 1 results, but was looking for 2).
控制器
def category
@category = params[:category_name]
@posts=Post.find(PostCategory.group(:post_id).pluck(:@category))
#↑The error point.
end
路线
get '/category/:category_name', to: 'pages#category'
观看次数
<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>
模型关系
belongs_to :post
has_one :post_category
accepts_nested_attributes_for :post_category
帖子类别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
我想做什么
例子。
我想找到 category_name params(casual)
和 PostCategory column(casual)
相同的列,然后从那里只找到为真的那些,并检索 Post
的所有记录 post_id
对应于 PostCategory column(casual, only true)
并在视图中反映它们。
谢谢。
首先,您的 category
方法存在问题,其中显示 :@category
。这可能需要说 @category
(没有冒号),以便方法主体的第二行显示为:
@posts=Post.find(PostCategory.group(:post_id).pluck(@category))
^
除此之外,您似乎正在尝试获取属于特定类别的所有帖子。你现在正在做的事情是行不通的,因为你查询 returns 一个布尔值数组,然后你使用布尔值来查找帖子。但是你需要 ID 来查找帖子,因为你不能将布尔值传递给 Post.find
.
为什么不直接做(未测试):
@posts = Post.find(PostCategory.where(@category => true).pluck(:post_id))
或者,在单个查询中(也未测试):
@posts = Post.joins(:post_category).where("post_categories.#{@category}" => true)
但是对于最后一个,您可能需要根据白名单检查 @category
变量以避免注入。编辑:正如 Max 在评论中所建议的那样,您可能希望将 where 子句更改为 where( post_categories: { @category => true })
以避免注入。
不需要修改数据库来添加类别的更好解决方案是设置更合理的规范化 table / 加入 table 设置:
# rails g model category name:string:uniq
class Category < ApplicationRecord
has_many :categorizations
has_many :posts, through: :categorizations
validates :name,
uniqueness: true,
presence: true
end
# rails g model categorization post:belongs_to category:belongs_to
class Categorization < ApplicationRecord
belongs_to :category
belongs_to :post
validates :post_id,
uniqueness: { scope: :category_id }
end
class Post < ApplicationRecord
has_many :categorizations
has_many :categories, through: :categorizations
end
处理这个问题的 Rails 要么在 categories#show 动作上处理(或使用嵌套路由):
resources :categories
class CategoriesController < ApplicationController
def show
@category = Category.find_by!(name: params[:id])
@posts = @category.posts
end
end
这当然意味着您有某种适当的设置,以确保类别的名称可以在 URL 的路径中使用。像 FriendlyID 这样的宝石是你的朋友。
@posts=Post.find(PostCategory.group(:post_id).pluck(:category))