1

I am playing around with render/redirects in my rails application, i have the following controller action

class MessagesController < ApplicationController

 def create
    @message = Message.new(body: params[:message])
    if @message.save
      head :created
    else
      flash[:notice] = "failed!"
      render "home/index"
    end

  end

here is my home/index.html.erb file

<% if flash[:notice] %>
    <div class="notice"><%= flash[:notice] %></div>
  <% end %>

<form>
  <textarea name="message" id="message" placeholder="Type your message..."></textarea>
  <input type="submit"></input>
</form>

I am submitting the form with jquery:

$(document).ready(function(){
  $('form').submit(function(e){
    e.preventDefault();
    var message_body = $('#message').val();
    $('#message').val('');
    $('#message').focus();
     $.ajax({
       url:    '/messages',
       method: 'post',
       data:   {message: message_body}
     });
  });
});

I have a validation in my form model that ensures that the message body cant be blank validates :body, presence: true

So when i create an empty message and hit submit, it renders the home/index template. (as it should)

Inside chrome, in the preview/response tabs of dev console i can see the flash message, however in my actual application, i cant see the flash notice until i refresh the page.. then it shows up.

Am i mis-understanding something about the ways pages are rendered/the differences between render/redirect_to or is this a turbo links issue ? I tried removing turbo links by removing //= require turbolinks from my application.js file and restarting my server.. still the same issue .

Any ideas ?

2 Answers 2

3

you defenitely misunderstand something about how flash_messages are dealing in rails.

the flash message is a one-timer for a rendering or a redirect (and then rendering).

if you set a flash[:notice] , the next time rails is rendering something, the flash_message will be available (and straight after it will be gone).

since you want to submit the form async, you should return the status, and then inside your ajaxcall you can go by the statuscodes and give some feedback for the user

something like this is possible (untested)

ajax({url, method, statusCodes: function() {
 200: function() {
   //success
 },
 500: function() {
  //failure
 }
});

and then inside your controller give back a 500 http code and the errors of the object

else
  render status: 500, json: {errors: @message.errors}
end
Sign up to request clarification or add additional context in comments.

3 Comments

thanks, but how would i then access the @message.errors inside my ajax statuscode function ?
well, just givien 500: functon(data) and then make a console.log(data) and you will see how you can use that. actually its just a json, so you can then just go in and for each key, take the error message and print that out
u will like this, for sure! stefan.haflidason.com/…
0

After playing around with this for a bit, and with help from the answers this is how i solved this :

My messages controller:

 def create
    @message = Message.new(body: params[:message])
    if @message.save
      head :created
    else
      render status: 422, json: { errors: @message.errors.full_messages}
    end
  end

My ajax call:

$(document).ready(function(){
  $('form').submit(function(e){
    e.preventDefault();
    var message_body = $('#message').val();

    $('#message').val('');
    $('#message').focus();

    $.ajax({
      url:      '/messages',
      method:   'post',
      data:     {message: message_body},

      error: function(data){
        console.log(data);
          var response = jQuery.parseJSON(data.responseText);
          var error_message = response.errors.join("\n");
          alert(error_message);
      }

    }); //end of ajax function 

  });   //end of submit function

});     //end of document.ready

1 Comment

well, ya, something like that. i personally dont go for success and error , instead i go for statusCodes, but you are throwing a 422 and that is defenitely a wrong (!) statusCode for what you are doing. a 422 is Unprocessable Entity. You should rather throw a 500 (which is also what rails is throwing default if "something went wrong")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.