对象正在被保存但是参数不是

时间:2015-10-26 22:00:48

标签: ruby-on-rails postgresql

我正在尝试使用rails制作一个简单的博客应用程序作为练习的一部分。现在,您可以直接在帖子的显示页面上添加对post_path的评论。

我希望能够保存一个Comment对象并将其嵌套在Post对象下,以便它们相关。

我的表单如下:

#_form.html.erb
<%= form_for @comment, :url => post_comments_path(@post)  do |f| %>
  <%= f.label :content %>
  <%= f.text_field :content %>
  <%= f.submit %>
<% end %>

我点击提交,然后我被转到评论控制员:

  #comments_controller.rb
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.new
    @comment.save(comment_params) # @comment is saved but :content is nil
    if @comment.save(comment_params)
      redirect_to post_path(@post)
    end
  end

如果我在创建操作中查看comment_params,我会看到: => {"content"=>"asdfasdfasdfasdf"}。注释会被保存,但是:content部分为空,如下所示:

=> #<Comment:0x007fd1da63ce60
 id: 4,
 content: nil,
 post_id: "1",
 created_at: Mon, 26 Oct 2015 21:45:22 UTC +00:00,
 updated_at: Mon, 26 Oct 2015 21:45:22 UTC +00:00,
 user_id: nil>

我的强力参数中列出了:content白色:

  def comment_params
    params.require(:comment).permit(:content, :post_id)
  end

这是我的模特......

#post.rb

class Post < ActiveRecord::Base

  has_and_belongs_to_many :tags
  has_many :comments
  belongs_to :user
  validates :title, :presence => true
  validates :body, :presence => true

  ###methods###
  def all_tags=(names)
    self.tags = names.split(",").map do |name|
        Tag.where(name: name.strip).first_or_create!
    end
  end
  def all_tags
    self.tags.map(&:name).join(", ")
  end

end

#comment.rb
class Comment < ActiveRecord::Base
  belongs_to :post
end

和我的架构。

  # schema..
  create_table "comments", force: :cascade do |t|
    t.string   "content"
    t.string   "post_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "user_id"
  end

  create_table "posts", force: :cascade do |t|
    t.string   "title"
    t.text     "body"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "user_id"
  end

  create_table "posts_tags", force: :cascade do |t|
    t.integer "post_id"
    t.integer "tag_id"
  end

  create_table "tags", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "username"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree

end

1 个答案:

答案 0 :(得分:2)

尝试更改为:

#comments_controller.rb
def create
  @post = Post.find(params[:post_id])
  @comment = @post.comments.new(comment_params)
  if @comment.save
    redirect_to post_path(@post)
  end
end

更新说明:

旧:

  # creates empty comment that belongs to @post
  @comment = @post.comments.new

新:

  #creates a comment that belongs to @post and has the content of comment_params
  @comment = @post.comments.new(comment_params)  

旧:

  @comment.save(comment_params)
  if @comment.save(comment_params)
    redirect_to post_path(@post)
  end
  # is the same as @comment.save({}) as far as save is concerned.  
  # save takes a hash for options.  It only uses the options it knows
  # So that is why it didn't complain.  It didn't find anything it knew 
  # in the hash comment_params.  So it just saved the empty comment

新:

  if @comment.save  # save the new comment that was generated with comment_params
    redirect_to post_path(@post)
  end