Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a view inside of another view (rails 4)

Hi I want to preface this by saying that I am new to coding.

I have an issue that I believe can be solved in two ways

A. by rendering a partial

B. by updating the controller

( I can totally be wrong but these are what I suspect lol)

I have two controllers/views "reviews" and "logs". and I want them to both appear on the same page.

How can I do this? I tried rendering a partial but I alway get an error.

and I tried the piece of code below:

which made my reviews show up on the page, but when I add

@log = @user.logs.all 

to it, it doesn't pull all the logs to the page like it does for the reviews.

def show
  @user = User.find_by_name(params[:id])
  if @user 
    @reviews = @user.reviews.all
    render action: :show
  else
    render file: 'public/404', status: 404, formats: [html]
  end
end
like image 420
Alicia T. Glenn Avatar asked Nov 07 '13 19:11

Alicia T. Glenn


People also ask

How do you render a partial?

You can render the partial view in the parent view using the HTML helper methods: @html. Partial() , @html. RenderPartial() , and @html. RenderAction() .

How do you use nested layouts Rails?

Nesting layouts is actually quite easy. It uses the content_for method to declare content for a particular named block, and then render the layout that you wish to use. So, that's the normal application layout.


1 Answers

First things first. Views refer to actions in controllers. So there can be several views for each controller or even none.

So, if you want to render @reviews and @logs on the same page you should first instantiate both instance variables in the same action and then render both partials in the same action. How do you do that? Easy. First you got to the controller you just showed and edit that show action.

def show       
  # You can set the variable in the if-clause 
  # And you also need to use static finders with a hash as an argument in Rails4
  if (@user = User.find_by(name: params[:id]))
     @reviews = @user.reviews.all 
     @logs = @user.logs.all
  # You don't need to call render explicitly 
  # if you render the view with the same name as the action 
   else
     render file: 'public/404', status: 404, formats: [html]
   end     
end

Second: you go to your /app/views/reviews/show.html.erb template and put both partials there like this (this is just an example, adjust your markup to fit your needs).

<h1> Reviews and Logs</h1>
<div id="reviews_part">
 <%= render @reviews %>
</div>
<div id="logs_part">
  <%= render @logs %>
</div>

Now create 2 new partials /app/views/reviews/_review.html.erb and /app/views/logs/_log.html.erb and put all the needed markup there (use regular variables review and log to adress the repeating objects). Rails will automaticaly repeat those partials as many times as needed.

Or you can explicitely call the partial render

<div id="reviews_part">
  <% @reviews.each do |review| %>
   <%= render review %> 
        which is the same as
   <%= render partial:"reviews/review", locals:{review:review} %>
  <% end %>
</div>
like image 193
Almaron Avatar answered Sep 19 '22 13:09

Almaron