使用friendly_id时如何find_by_id(对于多态关系)

Posted

技术标签:

【中文标题】使用friendly_id时如何find_by_id(对于多态关系)【英文标题】:How to find_by_id when using friendly_id (for polymorphic relations) 【发布时间】:2018-12-09 11:00:03 【问题描述】:

如何允许 find_by_id 工作,以便我的 cmets 可以通过 friendly_id 处理我的帖子?有没有其他方法可以做到这一点?

我已经安装了一个名为 friendly_id 的 Ruby gem,并使用它在我的博客文章中创建 slugs。这些博客文章通过polymorphic 关系拥有 cmets。我有这些相互冲突的方法,我认为是我的 cmets 无法工作并引发错误的原因:

undefined method 'comments' for nil:NilClass

cmets 控制器create方法中指向@comment = @commentable.comments.new comment_params

在我的评论模型中:

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
  has_many :comments, as: :commentable, dependent: :destroy
end

在我的评论控制器中:

class CommentsController < ApplicationController
  before_action :find_commentable

  def new
    @comment = Comment.new
  end

  def create
    @comment = @commentable.comments.new comment_params
    if @comment.save
      flash[:success] = "Thanks for sharing your thoughts!"
      redirect_back fallback_location: root_path
    else
      flash[:danger] = "There was an error posting your comment!"
      redirect_back fallback_location: root_path
    end
  end

  private

  def comment_params
    params.require(:comment).permit(:body, :email, :name)
  end

  def find_commentable
    @commentable = Comment.find_by_id(params[:comment_id]) if params[:comment_id]
    @commentable = Post.find_by_id(params[:post_id]) if params[:post_id]
  end
end

在我的帖子模型中: has_many :comments, as: :commentable

我的路线:

resources :comments do
  resources :comments
end

我的服务器日志:

app/controllers/comments_controller.rb:9:in `create'
Started POST "/posts/top-5-audio-industry-blogs/comments" for 127.0.0.1 at 2018-06-30 10:35:09 -0300
Processing by CommentsController#create as html
Parameters: "utf8"=>"✓", "authenticity_token"=>"[token]", "comment"=>"body"=>"Hey, thanks for checking out the article! Any questions? Just ask me here and I'll be happy to help.", "name"=>"name", "email"=>"email", "nickname"=>"", "commit"=>"Post Comment", "post_id"=>"top-5-audio-industry-blogs"
Post Load (0.0ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = $1 ORDER BY "posts"."created_at" DESC LIMIT $2  [["id", 0], ["LIMIT", 1]]
Completed 500 Internal Server Error in 27ms (ActiveRecord: 6.0ms)



NoMethodError (undefined method `comment' for nil:NilClass):

这是我能想到的唯一原因,因为它在没有蛞蝓的情况下工作。提前感谢您的帮助!

【问题讨论】:

可以显示服务器日志吗? @JagdeepSingh 感谢您的提问,我用日志更新了我的问题。 好的。不做Post.find_by_id(params[:post_id]),能不能改成Post.friendly.find(params[:post_id])看看能不能用? 哇,谢谢这个工作,我有点怀疑,因为我的commentable_id 接受整数作为表值。请将此创建为答案,我很乐意接受。 【参考方案1】:

根据docs,您需要查询CommentPost 模型,因为帖子有slugs 而cmets 没有。见下文:

def find_commentable
  @commentable = if params[:comment_id]
                   Comment.find_by_id(params[:comment_id])
                 elsif params[:post_id]
                   Post.friendly.find(params[:post_id])
                 end

  # You should also handle the case if `@commentable` is `nil` after above.
  redirect_to somewhere, error: 'Post/Comment not found' unless @commentable
end

【讨论】:

@Jake 我认为您在我之前编辑了答案,这会覆盖您建议的编辑。你能再做一次吗? 谢谢,我只是想知道我对每个 postcomment 使用 @commentable 而不是您提供的 if / else 语句是否有一个主要缺点?

以上是关于使用friendly_id时如何find_by_id(对于多态关系)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用friendly_id用随机数混淆用户ID

如何使用 friendly_id 从 URL 中删除特定单词 |铁轨上的红宝石

如何配置friendly_id gem的序列分隔符

更新时删除旧的friendly_id gem slug [关闭]

如何将 id 添加到 Friendly_id slug?

friendly_id:可选择更新 slug