View inside other view - ruby-on-rails

In a Rails application I have a view index.html.erb and a controller posts_controller.rb.
In the controller I have defined a variable:
def index
#posts = TableName.find...
and in the view I have:
<% #posts.each do |post| %>
If I access it via localhost/posts/index it works fine. But what I really want is to show this view inside other views so I'm using <%= render :template => 'posts/index' %> but I get this error message: "NoMethodError - You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.each"
How can I do this? Thanks

NoMethodError is triggered when you try to call methods on undefined object. In other word, you render posts/index in other views, but #posts instance variable is not defined in the other view. render template does not route the controller.

Related

undefined method `each' for nil:NilClass - but only when rendering on homepage

I have a model Person and I want to list all 'people' on the home page of my website.
I created a partial _index.html.erb for this, so I could use this list everywhere on my website. On index.html.erb, I render this partial.
Now both http://localhost:3000/people/ and http://localhost:3000/people/index run fine. However, I also wanted to use the index partial on my home page. There, it gives the following error:
undefined method `each' for nil:NilClass
Some parts of my code:
people/_index.html.erb
<h2>The following people exist:</h2>
<table>
<tr>
<th>Name</th>
</tr>
<% #people.each do |p| %>
<tr>
<td><%= p.name %></td>
</tr>
<% end %>
</table>
people/index.html.erb
<%= render 'people/index' %>
pages/index.html.erb (This is my home page)
<h1>Homepage</h1>
<%= render 'people/new' %>
<%= render 'people/index' %>
routes.rb:
Rails.application.routes.draw do
root 'pages#index'
get 'pages/index'
get 'people/index'
resources :people
end
Part of people_controller.rb:
class PeopleController < ApplicationController
def index
#people = Person.all
end
def show
#person = Person.find(person_params)
end
...
Somehow, rendering people/new (also a partial) works perfectly fine if I comment out <%= render 'people/index' %>.
Searching for this error leads mainly to the solution "you didn't properly define #people in the controller". However, why does it then work fine on the /people/index page but not when rendering it on the homepage? Is it a routing issue?
I hope that my question is clear and that I posted enough code snippets, thanks in advance for your help!
Your PagesController, which is called when you hit the pages/index route when rendering the homepage, doesn't have #people defined, so #people ends up being nil, and the error occurs.
You need to add #people = People.all somewhere in your PagesController, since PeopleController doesn't actually get called when you access the homepage.
If you check your development.log you will see PeopleController does not get called when you access the homepage and the people/_index partial renders.
undefined method 'each' for nil:NilClass means that you are calling each on something you think is there, but isn't. In this case your calling #people.each, but #people is actually nil. So you see that error. In your controller set #people = People.all in the action/method that is actually fueling that page. So if you are on the show page, it would go in the show method. On the edit page, makes sure that code is in the edit method.

Render partial from controller and from view

In my Rails app, I get to render an erb file from a controller and from another erb file like so:
# a_controller.rb
class AController < ApplicationController
def index
render 'lista'
end
# b_controller.rb
class BController < ApplicationController
def index
render 'listb'
end
# lista.html.erb
<%= render 'list' %>
# listb.html.erb
Some content that I want to keep
<%= render 'list' %>
# _list.html.erb
Hello
As you can see lista is only rendering the partial _list.
What I wanted to do was to call <%= render 'lista' %> from within listb.html.erb.
But when I do so, I get an error message saying that the partial _lista is not found.
Do you have an ideas?
lista.html.erb is a page, not a partial. Your code is looking for a partial called lista but it does not exist.
I really think you should create a new partial called _lista, you can render it in lista.html.erb and listb.html.erb. Your controller can still render 'lista' which will render the partial _lista.
You need to create _list.html.erb partial (any file name) file for access it with in lista.html.erb or listb.html.erb after that you can access as you want.
For example:-
# lista.html.erb
<%= render 'listb' %>
In lista.html.erb we can call listb (_listb.html.erb) file that are in current directory.
you should create a partial with name _lista.html.erb or you can change your file name from lista.html.erb to _lista.html.erb.
currently file lista.html.erb is not a partial that's why when you try to render lista partial, rails produce a error for you
#lista.html.erb
##assuming list is in lista/list.html.erb
<%= render 'lista/list' %>

Accessing first row in an object

<% question = #questions.try(:first) %>
<h1><%= question.title %></h1>
I'm trying to use the above code to grab the first question from a Questions model, and then display it's title in HTML. However, I'm throwing the error undefined method 'title' for nil:NilClass
Autogenerated RoR files use the question.title line... why isn't it working here?
question.title raises error as undefined method 'title' for nil:NilClass that means question is set as nil. You set question using
<% question = #questions.try(:first) %>
It means either #questions is nil or there #questions.first returns nil.
Make sure that you set #questions instance variable in the Controller's action which renders this particular view.
def action_name
#questions = Question.all
end
Also, if you just want to show only the first question record in your view and you are not going to use #questions anywhere then just set
def action_name
#question = Question.first
end
and use it in the view directly as:
<h1><%= #question.try(:title) %></h1>
It looks like #question is nil. Have you assigned #question in your controller action. Can you show your code in your controller action?

Rendering Rails partial view (with issues reading the Rails API)

I have a jQuery post submitting a form to a controller create action, which works great. If the save was successful I would like the create action to return a different form so the success callback will insert this form. Is this possible?
Here's my code:
def create
#event = Event.new(params[:event])
if #event.save
# This is where I would like to render a different controller action's view.
render :controller => "shows", :action => "new", :layout => false
else
render action: "new"
end
end
For some reason it will not render the "shows/new" template. It keeps rendering the current controller's new template without the layout. What am I missing here?
As an aside, I had a look at api.rubyonrails.org and tried to look up the render method. I found it listed as render(context,options), but can't for the life of me find out what the valid options are. This seems to be a common pattern for a lot of methods. How do I find out? It will certainly help me figure out what my options are, and perhaps give various things a try.
Thanks,
Dany.
ADDED: I have now used render "shows/new", :layout => false in my controller action, which is working. In my new.html.erb for Shows I have declared <%= render "/shows/form" %>. Unfortunately I am now getting 500 error. I found this in development.log:
ActionView::Template::Error (undefined method `model_name' for NilClass:Class):
1: <%= form_for(#show) do |f| %>
2: <% if #show.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#show.errors.count, "error") %> prohibited this show from being saved:</h2>
app/views/shows/_form.html.erb:1:in `_app_views_shows__form_html_erb___1397093944823648986_2158339140'
app/views/shows/new.html.erb:3:in `_app_views_shows_new_html_erb__1152608637968596369_2158584080'
app/controllers/events_controller.rb:61:in `create'
I'm not entirely sure what's causing this...
Seems you missed: 2.2.3 Rendering an Action’s Template from Another Controller
Try:
render "shows/new", :layout => false

Render cached action of another controller inside erb template

I want to render action inside my erb template.
<div>
<%= render :controller => :tags, :action => :tag_cloud %>
</div>
This block throws exception: undefined method `formats' for nil:NilClass
Also I want to tag_cloud action to be rendered from cache. Is that possible?
Regards,
Alexey Zakhaov
Just remind that render :action does not run the tags controller, it just renders the tag_cloud erb with the variables you have defined in your current controller.
So you have to define in your controller all the instance variables you need in your template, including the one on which the formats method is called.

Resources