I render an instance of a model into a partial with the following code <%= render #places %>.
I created _places.html.erb. I thought I could use the following code since the render method is supposed to iterates trhough the places collection :
<li>
<%= link_to place.name, place %>
</li>
I get this error : undefined local variable or method 'place' for #<#<Class:0x007fc1c0a4e6b8>:0x007fc1c05050a8>
I have to use to make it work :
<% #places.each do |place| %>
<li>
<%= link_to place.name, place %>
</li>
<% end%>
try this:
<%= render :partial => 'places.html', :collection => #places, :as => :place %>
Or, if you have the partial file as singular name, you can do it like this(without the variable :as)
<%= render :partial => 'place.html', :collection => #places %>
Related
Here is the code
Model:
Category has many subjects
View:
show:
<% category.subjects.each do |subject| %>
<div class="container">
<%= render partial: "layouts/trial", :locals => {:subject => subject} %>
</div>
<% end %>
layouts/trial:
<%= description(#subject) %>
trial_helper.rb
module TrialHelper
def subject
#subject ||= []
end
def description(subject)
#des = "#{subject.content}"
end
end
turn out
ActionView::Template::Error (undefined method `content' for nil:NilClass):
1: <%= description(#subject) %>
I've tried using
<%= render partial: "layouts/trial", :locals => {:subject => #category.subject} %>
and
def description(subject)
#des = "#{#subject.content}"
end
But it's still not work. What is the problem?
Probably your subject is nil in your layouts/trial.
The best approach is to debug and check where the problem is occurring.
You can set in your layouts/trial something like <%= raise #subject.inspect %> and if it really returns nil, we can confirm that this code here <%= render partial: "layouts/trial", :locals => {:subject => subject} %> isn't working as expected.
change
<%= description(#subject) %>
to
<%= description(subject) %>
locals are passed as local variables not instance variables
Right now I have a rails partial that looks like this:
<%= render :partial => "/talk/partials/comment", :collection => #comments, :locals => {:votes => #votes} %>
I am passing in a collection of comments and another local variable.
That comment partial then goes right into using the comment variable and works fine.
I have since made another partial called '/talk/partials/comment_2014'. When I try this, I am getting the error undefined local variable or method 'comment'. From what I can gather, when I have a different partial name, something with the variable also changes. I would like to keep the same comment variable for the new partial ''/talk/partials/comment_2014'. How would I go about doing this?
Something I tried which did not work was the following:
<% #comments.each do |comment| %>
<%= render :partial => "/talk/partials/comment_2014", comment: comment, :locals => {:votes => #votes} %>
<% end %>
which did not work either.
You can do it this way
<% #comments.each do |comment| %>
<%= render "/talk/partials/comment_2014", comment: comment, votes: #votes %>
<% end %>
Or
<% #comments.each do |comment| %>
<%= render partial: "/talk/partials/comment_2014", locals: { comment: comment, votes: #votes } %>
<% end %>
Notice in the second way the comment is inside the locals.
I have a table of accounts and venues where an account can have many venues.
I'm displaying all the accounts as partials on the accounts index page and would like for each one to include the names of the venues linked to them.
Heres what I have:
account partial
<%= link_to free_account do %>
<div class="account_partial">
<span class="account_header"><%= free_account.name %></span> - <span class="free_account_highlight">(<%= free_account.role %>)</span><br>
<%= render :partial => 'venues/account_venue', :collection => #account.venues %>
</div>
<% end %>
account_venue partial
<%= venue.name %>
I'm getting this error:
NoMethodError in Accounts#index
undefined method `venues' for nil:NilClass
Extracted source (around line #12):
12: <%= render :partial => 'venues/account_venue',
:collection => #account.venues %>
Any help would be much appreciated!
edit
accounts_controller
class AccountsController < ApplicationController
load_and_authorize_resource
def index
#accounts = Account.all(:include => :venues)
end
end
accounts index.html.erb
<div id="narrow_container">
<div class="free_accounts_container">
<h2 class="show_orange">Free accounts</h3>
<%= render :partial => 'free_account', :collection => #accounts %>
</div>
<div class="premium_accounts_container">
<h2 class="show_orange">Premium accounts</h3>
<%= render :partial => 'premium_account', :collection => #accounts %><br><br>
</div>
<div class="clearall"></div>
<div class="button">
<%= link_to 'add account', new_account_path %>
</div>
</div>
_free_account.html.erb
<%= link_to free_account do %>
<% if free_account.role == "free" %>
<div class="account_partial">
<span class="account_header"><%= free_account.name %></span> - <span class="free_account_highlight">(<%= free_account.role %>)</span><br>
<div class="owner_details">
<span class="pre_account_highlight">Owners username:</span><span class="account_highlight"><%= free_account.user.username %></span>
<span class="pre_account_highlight">Owners e-mail:</span><span class="account_highlight"><%= free_account.user.email %></span>
</div>
<div class="account_details">
</div>
<%= render :partial => 'venues/account_venue', :collection => #account.venues %>
</div>
<% else %>
<% end %>
<% end %>
update
If I change the partial call to:
<%= render :partial => 'venues/account_venue', :collection => #accounts %>
and the account_venue partial to just read 'test' it loads without error but displays the word test 4 times (theres 4 account records) if I add a new account record it displays the word test 5 times.
You need to set #account to something in your controller, and that model instance should be joined to (or include) the Venues model. Like so:
#account = Account.find(params[:id], :include => :venues)
Edit: I take it you have already set up your Account and Venue models with has_many and belongs_to relationships?
Edit two: I see now that you're trying to access Accounts#index, in which case the code above should be changed to something like (since we're not looking at one specific account):
#accounts = Account.all(:include => :venues)
Edit three: Now that you've posted the controller and partials code as well, a couple of things stand out; When rendering a partial using a collection the resulting object inside the partial derives its name from the partial and not the collection. From the Rails Guides:
"When a partial is called with a pluralized collection, then the
individual instances of the partial have access to the member of the
collection being rendered via a variable named after the partial."
In your partial _account_venue.html.erb you have <%= venue.name %> - this needs to be changed to <%= account_venue.name %>.
Secondly, in _free_account.html.erb, where you call the account_venue partial, you're referring to a collection object named #account - where does this come from? Since the free_account partial is also called with a collection, the object you should be using will be called free_account - indeed you are referencing it by this name earlier in the same partial when you do <%= free_account.name %>. So the render partial call should look like this:
<%= render :partial => 'venues/account_venue', :collection => free_account.venues %>
Hope this helps!
Looks like your not assigning #account to anything. Should this be free_account instead?
I am working on a app where you can add task etc. I know this is kind of weird but I just like to see how others would implement this. How would you change the following code into a helper method and use it?
The original code
<h2>My Tasks</h2>
<% task = #work.tasks %>
<% if task.empty? %>
<%= link_to 'Create a new task', new_task_path %>
<% else %>
<%= render :partial => 'notes/note', :locals => {:note => #note} %>
<% end %>
My way of doing a helper method
def task_check
task = #work.tasks
if task.empty?
link_to 'Create a new task', new_task_path
else
render :partial => 'notes/note', :locals => {:note => #note}
end
end
In my view
<%= #work.task_check %>
Personally, I wouldn't extract this out at all, this is view logic and it belongs in the views. It definitely doesn't belong in a model, but it could arguably be extracted into a helper. I'd change it slightly:
<h2>My Tasks</h2>
<% if #work.tasks.blank? %>
<%= link_to 'Create a new task', new_task_path %>
<% else %>
<%= render :partial => 'notes/note', :locals => {:note => #note} %>
<% end %>
Calling blank? instead of empty? will work even if #work.tasks is nil
.
You can't define a helper in the model. It won't have access to render, link_to or any other controller or view methods. So just define your method almost exactly as is in a file in your helpers directory, maybe application_helpers.rb or work_helpers.rb:
def task_check(work, note)
task = work.tasks
if task.empty?
link_to 'Create a new task', new_task_path
else
render :partial => 'notes/note', :locals => {:note => note}
end
end
And then call it in your view like so:
<%= task_check(work, note) %>
this is the code :
<ul >
<% items.each do |item|%>
<%= render :partial => "somepartial", :locals => { :title => item.title} %>
test_text
<% end %>
</ul>
the partial:
<li><a><%= title %></a></li>
and the out put is :
<ul >
<li><a>item1</a></li>
<li>test_text</li>
<li><a>item2</a></li>
<li>test_text</li>
<li><a>item3</a></li>
<li>test_text</li>
</ul>
< li > tags around the test_text is extra. Partial and the model is not related, so do not suggest me to use collection method. When partial is rendered inside the each loop, rails does not put li tags around it, but the anything except the partial gets li tags around them.
The question is not entirely clear to me, so maybe i should refrain from answering.
But, i would propose to use haml, which gives you much cleaner views.
Your main view would become:
%ul
= render :partial => "items/item", :collection => items
and your partial items\_item.html.haml would look like this
%li
%a
= item.title
I don't see a real link inside your li-item, so maybe you want something like:
%li
= link_to item.title, item_path(item)
Instead of this:
<% items.each do |item|%>
<%= render :partial => "items/item", :locals => { :title => item.title} %>
<% end %>
Try this:
<%= render :partial => "items/item", :collection => items %>