简体   繁体   中英

How to set up nested resources controller in Rails 4?

I have 3 models in my application. User (via Devise), post, and reply. User can be parent of both posts and replies, and reply belongs to users and posts.

For some reason it doesn't save replies to database. On output i can not see user_id . The function i used to create @reply is current_user.replies.create(reply_params) . Also html outputs braces seem bit odd to me. Why is only :comment in :reply s braces? Any idea what i did wrong?

Models:

              class Post < ActiveRecord::Base
                belongs_to :user
                has_many :replies
                validates_presence_of :title, :tekst
                validates :tekst, length: {minimum: 10}
              end

              class User < ActiveRecord::Base
                devise :database_authenticatable, :registerable,
                :recoverable, :rememberable, :trackable, :validatable

                has_many :posts, dependent: :destroy
                has_many :replies

               end

            class Reply < ActiveRecord::Base
              belongs_to :post
              belongs_to :user
              validates_presence_of :user, :post, :comment
              validates :comment, length: {minimum: 10} 

             end

Controller:

       class RepliesController < ApplicationController
   before_action :set_post, only: [:new, :index, :create]
   before_filter :authenticate_user!
  def index
    @replies = @post.replies
  end

  def new
    @reply = Reply.new
  end

  def create
    @reply = current_user.replies.create(reply_params)

    respond_to do |format|
      if @reply.save
        format.html { redirect_to @post, notice: 'Reply was 
        successfully saved' }
        format.json { render json: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: 'Wrong entry' 
        }
    end
    end
  end

  private

  def reply_params
    params.require(:reply).permit(:comment, :post_id)
  end

  def set_post
    @post = Post.find(params[:post_id])
  end
end

Form:

<%= form_for [@post, @reply] do |f| %>
  <%= f.text_field :comment %>
  <% f.hidden_field :post_id, value: @post.id  %>
  <%= f.submit %>
<% end %>

Schema:

  create_table "replies", force: :cascade do |t|
    t.integer  "post_id"
    t.integer  "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.text     "comment"
  end

  add_index "replies", ["post_id"], name: "index_replies_on_post_id"
  add_index "replies", ["user_id"], name: "index_replies_on_user_id"

And how it looks at output:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"lot of nubers",
"reply"=>{"comment"=>"sdfsddasd"}, "commit"=>"Create Reply", 
"post_id"=>"1"}

It's failing because you are not associating a post with the reply. Try this...

def create
  @reply = @post.replies.new(reply_params)
  @reply.user = current_user

  respond_to do |format|
    if @reply.save
    ...
  end
end

Also, notice that you should instantiate the reply (with new , instead of create ), then save it.

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