Exbi
Exbi

Reputation: 970

Two render statements within Ruby method and response to JQuery AJAX call

I have a number of existing methods within a controller. Each one of those methods needs validation.

To do this I have created a validation method within the application controller.

I want to call this validation method from the start of each individual method, which will check that the user has the required groups before continuing. The validation method returns true or false. If the validation methods returns false, the browser is redirected to a 'validation failed' page and the rest of that method is not executed. The original method is called using JQuery.

I will show some code and then explain what the problem is:

Jquery Ajax Request: (generic code but just to illustrate)

jQuery.ajax({
    url:"examplecontroller/examplemethod/" + ID,
    success: function(data,textstatus,XMLHttpRequest)
    {
    }
})

Method JQuery Request Calls:

def examplemethod
    id = ExampleDatabase.find(params[:id])

    #redirect to validationFail page if validation check returns false#
    render "/validationFail" if !(check_groups(id, "type"))

    ...other code etc...

    render :text => done

end

End Of Validation Method:

def check_groups(id, type)

    ... other code etc ....

    if userGroups.include? requiredGroup then
        return true
    else
        return false
    end
end

Regarding this line which calls the validation method-

render "/validationFail" if !(check_groups(id, "type"))

I did it like this because I just want a short, concise, one-line bit of code that I can just stick at the beginning of each method which either validates, and allows the rest of the method to be executed. Or it doesn't validate and it stops execution of the rest of the method.

My problem is that having the second 'render' line seems to invalidate the first one. If I have the second 'render' line in, the first one does not redirect to the 'validation fail' page. If I take the second validation line out, then there is no response to the JQuery Ajax call (assuming the method validates and is executed fully). This causes an error in Firebug, and obviously my AJAX 'success' code is not executed.

I know I could use IF statements to render one or the other, ie:

def examplemethod
    id = ExampleDatabase.find(params[:id])

    if !(check_groups(id, "type")) then
        render "/validationFail"
    else

        ...other code etc...

        render :text => done

    end
end

But I don't really want to go through and restructure each method like that, I'd rather just use a simple line at the beginning of each method that either returns true and continues, or returns false and doesn't continue.

It's strange (to my limited knowledge) that the second render affects the first, seeing as I thought using render would stop subsequent code executing...I've looked into using redirect_to instead of the first render, but I couldn't get this to work.

Can anyone suggest a better way of doing this?

Upvotes: 0

Views: 285

Answers (1)

Veraticus
Veraticus

Reputation: 16084

I think what you're looking for here is a before_filter. before_filters allow you to execute code and render content before selected actions, cancelling the action if the filter returns false. The documentation for filters can be found here, but for a piece of example code, you're likely looking for something like this:

def TestController < ApplicationController
  before_filter :check_groups

  def examplemethod
    id = ExampleDatabase.find(params[:id])

    render :text => 'done'
  end

  private

  def check_groups
    if !(check_groups(id, "type"))
      render '/validationFail'
      return false
    end
  end
end

Returning false in the before_filter will halt execution of the action, preventing other filters (or the action itself) from being called. If you use this method all over the place, you can even put it in your application controller, and you can throttle which methods before_filter executes on by reading up more on it in the documentation.

Upvotes: 1

Related Questions