简体   繁体   中英

object is being saved but the params are not

I am trying to make a simple blog app with rails as part of an exercise. Right now, you have the ability to add a comment on the post_path directly on show page of a post.

I'd like to be able to save a Comment object and have it be nested under a Post object so they are related.

My form looks like this:

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

I click submit and I am transported to the comments controller:

  #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

if I look at comment_params inside the create action I see: => {"content"=>"asdfasdfasdfasdf"} . The comment gets saved, however the :content portion is empty as you can see below:

=> #<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>

I do have :content white listed in my strong params:

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

Here are my models..

#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

and my schema.

  # 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

Try changing to:

#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

Update with explanation:

old:

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

new:

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

old:

  @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

new:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM