max
max

Reputation: 3

Rails3 rendering action from another controller

i want to render an action from another controller, but i get the error:

undefined method `formats' for nil:NilClass

<script>
$("#validate_company").live("keyup", function() {
 $("#company_info").html("<%= escape_javascript(render(:controller => 'live_validation', :action => 'validate_client_company')) %>");
});
</script>

This is the Controller:

class LiveValidationsController < ApplicationController

def validate_client_company
  if params[:first_name].length > 0
    @client = Client.find_by_company(params[:company])
    if @client.nil?
      @message = "<img src='/images/accepted_48.png' alt='Valid Username'/>"
    else
      @message = "<img src='/images/cancel_48.png' alt='Invalid Username' /> Name taken"
    end
  else
    @message = ""
  end
  render :partial => "message"
end

end

The partial _message is just

<%= @message %>

Upvotes: 0

Views: 2615

Answers (4)

max
max

Reputation: 1

Got it to work!

<script>
  $("#validate_company").live("keyup", function() {
        $("#company_info").load("/live_validations/validate_client_company",{company:$('#validate_company').val()});
  });
</script>

Upvotes: 0

nathanvda
nathanvda

Reputation: 50057

You seem to be mixing up stuff.

You have html inside your controller-method? That should be in your view. For each controller-method, normally a view with the same name is rendered, except if you explicitly call render from within your controller-method.

You do not write html in your controller. You write html in the view, and sometimes you have helpers to make your views more readable.

Secondly, in your first piece of code, which is some view-code, i hope. The view is prepared at server-side and then sent to the client. You can render another view, a partial, from a view. But this does not load data live.

How i would fix this. Inside your views where you want to dynamically render the validation:

<script>
  $("#validate_company").live("keyup", function() {
    $("#company_info").load("<%= url_for :controller => 'live_validations', :action => 'validate_client_company' %>");
  });
</script>

Then inside your controller you write:

class LiveValidationsController < ApplicationController

  def validate_client_company
    if params[:first_name].length > 0
      @client = Client.find_by_company(params[:company])
      @error = @client.nil? ? :valid_username : :invalid_username
    else
      @error = nil
    end
    render :partial => "message", :layout => false
  end

end

Inside your app/helper/live_validations_helper.rb you add a method

def get_validation_message(error)
  if error == :invalid_username
    image_tag('/images/cancel_48.png', :alt => 'Invalid Username') + "Name taken"
  elsif error == :valid_username
    image_tag('/images/accepted_48.png', :alt => 'Valid Username')
  end
end

and inside your message view you write something like:

<%= get_validation_message(@error) %>

Upvotes: 2

F&#225;bio Batista
F&#225;bio Batista

Reputation: 25270

You probably want something like this:

<script>
$("#validate_company").live("keyup", function() {
 $("#company_info").load("<%= url_for :controller => 'live_validation', :action => 'validate_client_company' %>");
});
</script>

But the rest of your code is kinda of messed up... Rendering a partial from inside a controller?

Upvotes: 0

yfeldblum
yfeldblum

Reputation: 65435

render :action => does not run the associated controller method.

It simply renders the template that Rails would, by default, have associated with the action. That is to say, if the action validate_client_company simply called render without passing any arguments, Rails would look for a template in a folder with the same name as the controller and with a name with the same name as the action. Calling render :action => simply looks for that same template and renders it.

Best guess is that Rails cannot find a template named validate_client_company. I expect that none exists, because the action validate_client_company renders a partial named message instead of rendering a template with the default name for that action.

In the action which renders the script, you need to set up the instance variables and then in the template for that action you need to use the following:

render :partial => 'live_validations/message'

It certainly makes sense to have mini MVC stacks within the larger MVC stack, so that you can run sub-actions within running larger actions. For this scenario, you may wish to look at Cells. However, you cannot do this with Rails by itself.

Upvotes: 2

Related Questions