Code-MonKy
Code-MonKy

Reputation: 2086

How to fit a form into a rails show after another form? Multiple same forms

I am making this form for a reply function in a blog-like app with the same recipe as the comment in which it should nest. (Comment recipe)

I get the following error when I try to view my app in the browser:

No route matches {:action=>"index", :post_id=>"10", :controller=>"replies", :comment_id=>nil} missing required keys: [:comment_id]

This is my reply view file for my replies/_form.html.haml

%h5 Reply
= form_for [ @post, @comment, @reply ] do |f|
  %p
  = f.label :name 
  %br
  = f.text_field :name
  %p
  = f.label :talk
  %br
  = f.text_area :talk
  %p
  = f.submit 'Submit'

This is my replies controller getting a hold on the comments_id much like the recipe said I should do between the comments and the post_id:

class RepliesController < ApplicationController
  def create
    @reply = Reply.new(reply_params)
    @reply.comment_id = params[:comment_id]
    @reply.save
    redirect_to post_path(@reply.comment.post)
  end
end

And this is my id passing in the comments show controller as it is similar in the post show controller. Or should I add something more to the post show controller now?

def show
    @reply = Reply.new
    @reply.comment_id = @comment.id
end

I tried adding replies though the rails console. They show up neatly, so I think my routes file works. Something with the id's and the handling of the collections isn't going great though. The form part is not working.

I don't like adding gems if I don't have to, I want to understand my app.

EDIT: I should probably add that my app has a view that looks like a indexing-form system in a indexing-form system. Below the post there are comments - with a form, and below these there are replies - with a form.

EDIT 2: First argument in form cannot contain nil or be empty is what I get now al the time.

EDIT 3: I still can't make my forms under the comments. This is my routes file, maybe it clarifies.

resources :posts do
  resources :comments do 
    resources :replies do
    end
  end
end

I am debugging now by making print outs and found out that in my _form haml file for a reply rails can find the @post, but not the comment nor replies (but they have to be created of course with the form), while I can get almost exactly the same structure to work in my _form for a comment. Is it even possible in Rails to have multiple forms printed out on the same page? Still all help is appreciated!

EDIT 4: I have gotten a little further. Now Rails says:

No route matches {:action=>"index", :post_id=>"2", :controller=>"replies", :comment_id=>nil} missing required keys: [:comment_id]

As a direct effect of changing my show action in the post controller:

def show
  @post = Post.find(params[:id])
  ## create a blank comment
  @comment = Phase.new
  @comment.post_id = @post.id 
  ##
  ## The same for a blank reply
  @reply = Reply.new
  @reply.comment_id = @comment.id
  ##
end

The last line of this action seems to not make any difference. Now I just need to be able to grab this comment_id in the reply form and then I am done. Nearly a week of struggle.

Upvotes: 0

Views: 207

Answers (1)

george
george

Reputation: 163

I believe you may not be getting a @comment.id because you are doing Comment.new(reply_params) and objects only get id fields whens you use .create OR .save after instantiating with new. Let me know if this helps!

Because of this you are getting the nil error for @comment in the form.

EDIT

It seems like you are looking to get the comment_id from the form, another solution would be to get it from the URL by having this happen under comments path. You'd have to nest your resources so it's something like comments/:id/reply/:reply_id or comments/:id/reply/new.

Here's some great examples for nested attributes: http://guides.rubyonrails.org/routing.html#nested-resources

SECOND EDIT

Okay, I was a bit confused because typically you would have the form in new not in show. Either way I would be looking at the instance variables being passed in. How do your associations look?

if it's Post has_many :comments and Comment has_many :replies, then you can do something like this in your show actions:

def new
  @post = Post.find(params[:post_id]
  @comment = @post.comments.find(params[:comment_id]) #scopes your search to only the comments belonging to this post
  @reply = @comment.replies.new
end

The more important point to get out of this is that each instance variable needs to be passed in. that being said, I'm not sure which ones are currently working for you

As far as create you should be doing something similar, creating through the associations. This rails magic handles all the foreign keys and assigning the id's etc:

def create
  @post = Post.find(params[:post_id]
  @comment = Comment.find(params[:comment_id])
  @reply = @comment.replies.new(reply_params)

  if @reply.save
    # some logic
    redirect_to wherever_path
  else
    # other logic
    render :new
  end
end

The more important point to get out of this is that each instance variable needs to be passed in. that being said, I'm not sure which ones are currently working for you

Let me know how this works!

Upvotes: 0

Related Questions