Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AJAX call to render partial in Rails 3

I have a user's dashboard page where the left side has a sidebar with links like Projects, Blogs, etc. I want to be able to click a link such as the "Projects" link and then in the main area, the view for projects would load up (view would be a bullet list of projects) without having to refresh the page. I'm trying to make this happen with AJAX, but things are not working.

Here's how I think it's supposed to work. The user clicks on the sidebar link in show.html.erb

<%= link_to 'Projects', '/dash', remote: true %>

where /dash is configured to route to users#show in the config/routes.rb file like this:

match '/dash' => 'users#show'

And then, the show action is called inusers_controller.rb controller:

def show
    @user = User.find(params[:id])
    @projects = @user.projects

    respond_to do |format|
      format.html # renders show.html.erb
      format.js   # renders show.js.erb
    end
end

Where show.js.erb is executed. My show.js.erb file has this one line:

$('#ajax').html("<%= escape_javascript(render(:partial => 'projects/index')).html_safe %>");

And that is supposed to modify the #ajax div in my show.html.erb:

<div id="ajax">
  <%= render :template => 'projects/index' %>
</div>

The app/views/projects/index.html.rb takes in @projects and gives a list, like this:

<% @projects.each do |project| %>
  <p><%= project.name %></p>
<% end %>

Obviously, I'm doing things wrong because this is not working. What am I doing wrong? Is there some code I need to change elsewhere? I'm on Rails 3.2.13, so the lines //=jquery and //=jquery_ujs under app/assets/javascripts/application.js should have imported the necessary jQuery and AJAX functionality.

like image 832
Jack Avatar asked Jun 22 '13 01:06

Jack


1 Answers

The problem is that in your show.js.erb file you are trying to render a partial but you are passing it a file that is not a partial. Partial files begin with an underscore _.

So, to avoid duplicating code, here's what I'd do:

# app/views/projects/show.js.erb
$('#ajax').html("<%= escape_javascript(render :partial => 'index', :locals => { :projects => @projects } ) %>");

# app/views/projects/index.html.erb
<%= render :partial => 'index', :locals => { :projects => @projects } %>

# app/views/projects/**_**index.html.erb
# Include here the code that you previously had in index.html.erb
# Don't forget to change @projects to projects
<% projects.each do |project| %>
  <p><%= project.name %></p>
<% end %>

Also, you shouldn't use match in your routes, as you pretty much will never need your routes to be accessible by both GET and POST methods. So try to use get instead of match.

like image 150
Ashitaka Avatar answered Sep 27 '22 02:09

Ashitaka