使用另一个表中的ID创建新的表条目

时间:2014-12-27 20:39:01

标签: mysql ruby-on-rails ruby devise

我正在尝试将user_id(我可以访问用户详细信息)附加到已经附加到名为Park的页面的评论中。

我设置了三个表:Park,Comment和User:

class Park < ActiveRecord::Base

    has_many :comments
    has_many :users

end

class Comment < ActiveRecord::Base

    belongs_to :park
    has_one :user

end

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

   has_many :comments

   validates_presence_of :username
    validates :username, uniqueness: true

  def admin?
    admin
  end
end

如上所示,我正在为用户和授权使用Devise gem。

评论显示在Park上,因此它们是嵌套的:

park_comment GET    /parks/:park_id/comments/:id(.:format)      comments#show

我的评论控制器设置如下:

class CommentsController < ApplicationController
    before_action :authenticate_user!, only: [:create]
    before_action :authorize_admin!, only: [:delete]

    def create
        @park = Park.find(params[:park_id])
        @comment = @park.comments.create(comment_params)
        redirect_to park_path(@park)

    end

    def destroy
        @park = Park.find(params[:park_id])
        @comment = @park.comments.find(params[:id])
        @comment.destroy

        redirect_to park_path(@park)
    end

    private
    def comment_params
        params.require(:comment).permit(:comment, :user_id, :park_id)
    end
end

我已经能够从park_id振荡到user_id,但是在另一个术语中,权衡一直是非常重要的。

我只是尝试在评论表单中添加隐藏字段

<%= form_for([@park, @park.comments.build]) do |f| %>
<p>
<%= f.label :comment %><br>
<%= f.text_area :comment %>
<%= hidden_field_tag(:user_id, current_user.id) %>
</p>
<p>
        <%= f.submit %>
</p>
<% end %>

但这似乎没有产生任何结果。

我曾尝试过一些ActiveRecord加入工作,但它不想锁定我的创建所以我放弃了。现在花了一段时间,我确信有一个简单的解决方案,我只是没有看到。想法?

2 个答案:

答案 0 :(得分:0)

我不确定我是否理解正确,但看着你的代码,我可以看到一些问题。

首先,您创建一个隐藏字段但不使用表单助手。这就是为什么您的user_id在comment_params中不可见,导致您的

  

大胖子

:)。 尝试改变

<%= hidden_field_tag(:user_id, current_user.id) %>

<%= f.hidden_field(:user_id, :value => current_user.id) %>

但更好的想法就是删除隐藏字段并将控制器更改为

  def create
    @park = Park.find(params[:park_id])
    @comment = @park.comments.new(comment_params)
    @comment.user = current_user
    if @comment.save
      redirect_to park_path(@park)
    else
      ...
    end
  end

您现在可以从:user_id中删除comment_params,如下所示:

params.require(:comment).permit(:comment, :park_id)

实际上,你甚至不需要:park_id

答案 1 :(得分:0)

您的hidden_field_tag无效。它会创建一个单独的参数,而不是一个嵌套在您想要的参数键下。

我的建议是完全删除hidden_​​field并在控制器中指定current_user。

class CommentsController < ApplicationController

  def create
    @park = Park.find(params[:park_id])
    @comment =  @park.
                comments.
                create(
                  comment_params.
                  merge(user_id: current_user.id) # adding here, on creation
                  # or merge(user: current_user)
                )
    redirect_to park_path(@park)
  end

  def comment_params
    params.
    require(:comment).
    permit(:comment)
  end

end

为什么呢?因为否则用户可能会更改该hidden_​​field的值,并且您将错误地存储评论的user_id值。