【问题标题】:How to Submit Polymorphic Comments on Feed? [Error]如何在 Feed 上提交多态评论? [错误]
【发布时间】:2015-06-30 15:07:39
【问题描述】:

如果用户点击[+评论]按钮

他遇到了这只邪恶的野兽:

ActiveRecord::RecordNotFound in CommentsController#create
Couldn't find Comment with 'id'=
Line: @commentable = resource.singularize.classify.constantize.find(id)

活动/索引

<%= link_to activity.user.name, activity.user %>
<%= render "activities/#{activity.trackable_type.underscore}/#{activity.action}", activity: activity %>
<%= render "comments/comments", comments: activity.comments %>
<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name) %>

cmets/_form

<%= form_for new_comment do |f| %>
  <%= f.text_area :content, rows: 4, class: 'form-control', placeholder: 'Enter Comment' %>
  <%= button_tag(type: 'submit', class: "btn") do %>
    <span class="glyphicon glyphicon-plus"></span> Comment
  <% end %>
<% end %>

activities_controller

def index
  @activities = Activity.order("created_at desc").where(user_id: current_user.following_ids)
  @commentable = @activity
  @comment = Comment.new
end

错误可以在这里找到:

class CommentsController < ApplicationController
  before_action :load_commentable
  before_action :set_comment, only: [:show, :edit, :update, :destroy, :like]
  before_action :logged_in_user, only: [:create, :destroy]

    def index
        @comments = @commentable.comments
    end

    def new
        @comment = @commentable.comments.new
    end

    def create
        @comment = @commentable.comments.new(comment_params)
        if @comment.save
            redirect_to @commentable, notice: "comment created."
        else
            render :new
        end
    end

    def edit
        @comment = current_user.comments.find(params[:id])
    end

    def update
        @comment = current_user.comments.find(params[:id])
        if @comment.update_attributes(comment_params)
            redirect_to @commentable, notice: "Comment was updated."
        else
            render :edit
        end
    end

    def destroy
        @comment = current_user.comments.find(params[:id])
        @comment.destroy
        redirect_to @commentable, notice: "comment destroyed."
    end

  def like
    @comment = Comment.find(params[:id])
    @comment_like = current_user.comment_likes.build(comment: @comment)
    if @comment_like.save
            @comment.increment!(:likes)
        flash[:success] = 'Thanks for liking!'
    else
        flash[:error] = 'Two many likes'
      end  
        redirect_to(:back)
  end

private
  def set_comment
    @comment = Comment.find(params[:id])
  end

    def load_commentable
        resource, id = request.path.split('/')[1, 2]
        @commentable = resource.singularize.classify.constantize.find(id) #Here it is!
    end

    def comment_params
        params[:comment][:user_id] = current_user.id
        params.require(:comment).permit(:content, :commentable, :user_id, :like)
    end
end

错误来自这里的答案:How to Add Polymorphic Comments to Feed?

development.log

Started POST "/comments" for ::1 at 2015-04-23 20:12:14 -0400
Processing by CommentsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"hU1lxg2BMqSyBo8j2SGiEB4wZ3ez5kz/E64mp6ssbwBnh+DddyTtNQxY+IYCluHHvs2wIBxrtD5hQVA5sGtXBg==", "comment"=>{"content"=>"test"}, "button"=>""}
  [1m[35mUser Load (0.2ms)[0m  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 2]]
  [1m[36mHabit Load (0.1ms)[0m  [1mSELECT "habits".* FROM "habits" WHERE "habits"."user_id" = ?[0m  [["user_id", 2]]
  [1m[35mHabit Load (2.5ms)[0m  SELECT "habits".* FROM "habits"
  [1m[36mActsAsTaggableOn::Tag Load (0.3ms)[0m  [1mSELECT "tags".* FROM "tags" WHERE (LOWER(name) = LOWER('ingrain'))[0m
  [1m[35mComment Load (0.3ms)[0m  SELECT  "comments".* FROM "comments" WHERE "comments"."id" = ? LIMIT 1  [["id", nil]]
Completed 404 Not Found in 16ms

ActiveRecord::RecordNotFound (Couldn't find Comment with 'id'=):
  app/controllers/comments_controller.rb:61:in `load_commentable'

非常感谢!

【问题讨论】:

  • 请问你想用那条线做什么?看起来它正在解决Comment.find(id)。如果是这样,你能简化吗?另外,核心问题是@commentable 可以为 nil,而您并没有从我所看到的情况下防止这种情况发生。
  • 嘿@steveklein 是的,我认为我们可以简化为:undefined local variable or method 'id。我得到了这个 railscasts 剧集的代码:railscasts.com/episodes/154-polymorphic-association-revised。他还提供了另一种选择:def load_commentable klass = [Valuation].detect { |c| params["#{c.name.underscore}_id"]} @commentable = klass.find(params["#{klass.name.underscore}_id"]) end,然后将undefined method 'name' for nil:NilClass 作为第二行。
  • 我们需要确定可评论资源的名称和它的id。我们将从 request.path 中获取这些,方法是在每个斜线处拆分它并获取第二个和第三个元素,因此如果路径是 /valuations/1,这将是使用的两个元素。我们可以使用这些来设置@commentable,方法是调用singlularize.classify.constantize 来获取模型的类,然后调用find 来通过id 获取实例。不知道如何解决它@steveklein

标签: ruby-on-rails ruby model-view-controller feed


【解决方案1】:

问题是,为了让它工作,看起来它是为 cmets 设置为您在路由文件中评论的任何内容的嵌套资源

因此,如果您希望 cmets 参加活动,您可以:

resources :activites do
  resources :comments
end

这样,当#load_commentable 方法分离请求路径时,它会从前两个段中获取commentable 和id。

看起来,相反,您正在尝试将 cmets 用作顶级资源。

更新: 当您调用您的部分时,只需传递表单应使用的 url 助手。像这样:

<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name), create_url: :activity_comments_path %>

然后,在部分中,只需调用该帮助程序并将结果作为 url 选项传递 - 如下所示:

<%= form_for new_comment, url: send(create_url, new_comment.commentable)

【讨论】:

  • 我已经有了,但我也将它作为顶级资源。我将其作为顶级资源删除,现在我收到一条错误消息:undefined method 'comments_path' for ... line:&lt;%= form_for new_comment do |f| %&gt; 所以也许你正在做某事。
  • 当您将 new_comment 局部变量传递给部分时,尝试将其作为 activity.cmets.build - 如果使用嵌套资源的路径帮助程序没有生成路径,那么您可以简单地传递您也想使用路径助手。
  • 嗨,乔·马丁内斯刚刚和史蒂夫聊完。我们无法解决。可能是不可能的。你愿意聊天吗?谢谢乔!
  • 这绝对是可能的——你只需要通过路径助手到你的 cmets 部分。栈交换有聊天功能吗?
  • 看起来我们从来没有同时在线 - 哈哈。如果您在要点中发布您的观点和部分观点,我将向您展示我认为可以解决它的更改。
【解决方案2】:

load_commentable 操作之前,如果@commentablenil,您可以重定向到错误页面或其他内容。实际上,您正尝试在其他方法中访问此 nil 对象的属性(在出现此错误的情况下为 create)。

【讨论】:

  • 我很难实现你的意思:/问题出在我点击提交时,所以它们不是都为零,因为它需要先保存吗?您是否建议我在before_action :load_commentable 行中添加条件?没见过,所以我觉得我理解错了。对不起史蒂夫。
  • 当您 createcomment 时,您不希望 @commentable 有效(而不是 nil)吗?您只是为了方便而使用before_action - 如果您要在每个相关操作的开头移动该代码,您将永远不会对潜在的nil 对象进行操作。这就是为什么我不喜欢以这种方式使用before_action - 它不是很透明。在load_commentable 末尾可以添加redirect_to root_path if @commentable == nil。如果需要,我们可以建立聊天。
  • 让我们开始吧!我在您最近的评论中遇到了问题。想在这里见我:chat.stackoverflow.com/rooms/76194/…
猜你喜欢
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多