简体   繁体   中英

Render show view in a partial - Ruby on Rails

So I have a sidebar in my rails application. Basically, I have a grid full of images. When someone clicks on an image in the grid, I basically want the show view to be displayed in the sidebar. I'm clueless on how to do this.

I've tried copying and pasting the show view's html and erb into my _sidebar.html.erb partial. But I get variable errors. My partial is located in my layout folder. But I can move it if needed.

Here is an image of the application for a better idea of what I'm talking about.

这就是我的应用程序的样子。灰色部分是侧边栏部分。

Here's how to do it:


1) Include the sidebar partial in your layout :

#app/views/layouts/application.html.erb
<%= render "shared/sidebar" %>

This calls the _sidebar.html.erb partial in /app/views/shared :


2) Populate the "default" sidebar partial:

#app/views/shared/_sidebar.html.erb
...

The important thing to note here is that partials should never have @instance variables inside.

Partials have locals , which you can pass with the following command:

<%= render "shared/sidebar", locals: { variable: "value" } %>

Partials are meant to run on any part of your web application, and since @instance variables are present for a single "instance" of an object (IE @post won't be available in /users ), you can ensure partials are always populated by passing local variables to them.

This is why you received errors when copying your post#show code to your sidebar partial -- the instance variables present for the show action will not be present in other parts of the app.


3) Use JS to pull image objects

When someone clicks on an image in the grid, I basically want the show view to be displayed in the sidebar.

You need to be more specific - do you really want the "show" action to appear, or do you want parts of its functionality?

Either way, you'll be best using JS & ajax to pull the data:

#app/controllers/images_controller.rb
class ImagesController < ApplicationController
   layout Proc.new { |controller| !controller.request.xhr? }
end

#app/assets/javascripts/application.js
$(document).on("click", "img", function(e) {
   e.preventDefault();
   $.get($(this).attr("href"), function(data){
      $(".sidebar .image").html(data);
   });
}); 

This will take the rendered images#show action (without layout), and append it to your sidebar partial. This is what you asked for - I can change it if required.

Lets say that your model is called "Image".

In your "images/show.html.erb":

# This is a handy shortcut that will call the 'images/_image' partial. 
# Those two lines are exactly the same. 
<%= render @image %>
<%= render "images/image", image: @image %>

In your "_sidebar.html.erb":

<div id="sidebar-img"></div>

In your "images/_image.html.erb":

 # Code displaying your image, don't use any global variable.
 # 'image' is the name of the local variable

In your grid:

 # remote: true allows you to do an AJAX call
 <%= link_to image, remote: true do %> 
   # Something like that, I don't know your code
   <%= image_tag image.url %>
 <% end %> 

Create "images/show.js.erb", when clicking on a 'remote :true' link it will call this file.

 # set @image to Image.find(params[:id]) in your controller
 $("#sidebar-img").html("<%= render @image %>");

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