0

In my app, people can comment on pets' images. I am using the react example from here, although I changed quite a few stuff.

Right now, it is successful in displaying the existing comments. Now, when a user is creating a comment, I have to pass the comment body, user id, and pet id. I was trying to do the following:

var CommentForm = React.createClass({
handleSubmit:function()
    {
      var user=this.refs.user_id.getDOMNode().value.trim();
      var comment=this.refs.body.getDOMNode().value.trim();
      var pet_id=this.refs.pet_id.getDOMNode().value.trim();

      this.props.onCommentSubmit({comment:comment, user:user, pet:pet_id});
      if(!user||!comment||!pet_id)
        return false;
      var formData = $( this.refs.form.getDOMNode() ).serialize();
      this.props.onCommentSubmit( formData, this.props.form.action );

      // reset form
      this.refs.body.getDOMNode().value = "";
    },

render: function () {
return (
  <form ref="form" className="comment-form" action={ this.props.form.action } accept-charset="UTF-8" method="post" onSubmit={ this.handleSubmit }>
    <p><input type="hidden" name={ this.props.form.csrf_param } value={ this.props.form.csrf_token } /></p>
    <p><input type="hidden" ref="user" value={ this.props.user_id } /></p>
    <p><input type="hidden" ref="pet_id" value={ this.props.pet_id } /></p>
    <p><textarea ref="body" name="comment[text]" placeholder="Say something..." /></p>
    <p><button type="submit">Post comment</button></p>
  </form>
)
}
});

And apparently, it doesn't look like it is passing the pet_id correctly, because I am getting the error message

ActiveRecord::RecordNotFound in CommentsController#create
Couldn't find Pet with 'id'=

My CommentsController looks like

def create
    @pet = Pet.find(params[:pet_id])
    @comment = @pet.comments.new(comment_params)
    @comment.user = current_user

For further clarification, I have three models, Pets, Users and Comments, and when users make comments, the comment gets the user_id, and pet_id as its parameters.

edit:

My react component looks like

 <%= react_component('CommentBox', 
{:presenter => @presenter.to_json}, 
{:prerender => true}) %>

and my PetController looks like

def show
    @comments = @pet.comments
    @user = current_user
    @presenter = {
        :comments => @comments,
        :user => current_user,
        :pet_id => @pet,
        :form => {
            :action => comments_path,
            :csrf_param => request_forgery_protection_token,
            :csrf_token => form_authenticity_token
      }
user2857014
  • 507
  • 3
  • 10
  • 22
  • Hard to tell from what you have posted here. Is pet_id set in the react component correctly? When you perform the post is pet_id passed in the request back to the server? Have you setup rails with the correct routing so it knows what params[pet_id] is? – Stewart Dec 07 '15 at 02:55
  • hi @Stewart please look at my edit for how the react component is set up currently. In terms of your other two questions, I am wondering if "

    " passes the request back to the server. Also, the last question might be what I am lacking currently. Could you please elaborate how I can do it?
    – user2857014 Dec 07 '15 at 03:07
  • Can you post a dump of the incoming params to the server when you make the post reqest. I suspect that ref="pet_id" should be name="pet_id" in your hidden field – Stewart Dec 07 '15 at 04:18
  • Hey @Stewart thank you! I did what you suggested and realized that it wasn't actually passing any values! So just to see if it would have worked if the data was passed correctly, I just hardcoded the values, and it was finally working.. except now the page still refreshes. I am wondering if it is because I set :action => comments_path, in the PetController. Any ideas? I changed the path to many different things but none seem to work so far. – user2857014 Dec 07 '15 at 04:50

1 Answers1

0

So there are a few issues I can see. Firstly your using ref where you should be name.

<input type="hidden" ref="pet_id" value={ this.props.pet_id } />

should be

 <input type="hidden" name="pet_id" value={ this.props.pet_id } />

Your setting both an action and an onSubmit. Is there a reason to do this? Why not just read it from the props when you perform the ajax request? This is most likely causing your form to be submitted and the browser to load another page. The form submitting has nothing to do with what is on the server. The issue is in your client side code.

I would also consider putting your model values in to their own array. This is generally what rails expects back from the server. In your case it should be params[:pet][:id] not params[:pet_id]. Many of the rails active record methods such as update attributes can then be directly called giving you less verbose code.

@pet = Pet.find(params[:pet][:id])
@pet.update_attributes(prams[:pet])
@pet.save
Stewart
  • 3,023
  • 2
  • 24
  • 40
  • hi @Stewart, thanks for continuing to help me. In regard to your second paragraph, I think you are referring to action={ this.props.form.action } and onSubmit={ this.handleSubmit }, and removing the latter doesn't seem to affect the situation, so I think I can delete that. It is still refreshing the page though. Is there anything I can fix? I am wondering if the :action => comments_path has anything to do with it. I am still very new to both rails and react, so I really appreciate your help. – user2857014 Dec 08 '15 at 02:25
  • can you try removing action and see what happens – Stewart Dec 08 '15 at 03:16
  • I get "No route matches [POST] "/pets/2"". – user2857014 Dec 08 '15 at 03:40