简体   繁体   中英

Returning: A full page, JSON, and a partial HTML snippet from Ruby on Rails Controller

I know this question has been asked in part a few other times on SO but I was curious about doing it a different way. In my Ruby on Rails app I have an action called list on my UsersController.rb controller. I want this list to respond to 3 different things

  1. The page itself. Rending the whole page of users I specify
  2. A JSON list of users for the page I specify
  3. A partial view of just the rows for the page I'm specifying formatted as HTML.

Imagine a full page (header, footer, everything) with a table that has page 1 of users. When I click page 2 I want to kick off an ajax request back to the same controller action to give me just the html rows for page 2. I also want to persist my JSON API still allowing my controller to return JSON lists when asked. I imagine it looking someting like this.

class UsersController < ApplicationController
    def list
        respond_to do |format|
            format.html # RETURNS MY VIEW
            format.json # RETURNS MY JSON LIST
            format.partial_html # RETURNS MY PARTIAL HTML
        end
    end
end

Is there anyway to accomplish this in RoR? Or am I doomed into having to create another action in my controller just to return technically the same data?

Could I make this happen by specifying my own MIME type? Should I snake in the partial as an XML return type?

  1. Use format.js on the third line.
  2. Put the partial html on a partial, call it app/views/users/_html_rows.html.erb .
  3. render that partial both on the full html and on the js version.

You will have app/views/users/list.html.erb with the full html content, which will be something like this:

<html>
<body>
.....
<table id="my_table"><%= render 'users/html_rows', users: @users %></table>
</body>
</html>

You will have app/views/users/_html_rows.html.erb with:

<tbody>
  <% users.each do |user| %>
    <tr>
      <td>user.name</td>
    </tr>
</tbody>

Then you will have app/views/users/list.js.erb with:

$("#my_table tbody").html("<%= render 'users/html_rows', users: @users %>");

This probably will solve your problem.

You can add an additional mime type entry to work with respond_to . In config/initializers/mime_types.rb , add:

# htmlp means "html partial"
Mime::Type.register "text/html", :htmlp

In your controller you can now do:

def list
  respond_to do |format|
    format.html
    format.json
    format.htmlp { render layout: nil }
  end
end

And create a template called list.htmlp.erb with your partial content in it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM