Passing local variable to partial inside for each loop rails 3 - ruby-on-rails

This is my code for rendering the partial (the #parties collection is being generated correctly, I have tested that):
<% #parties.each do |party| %>
<div class="item">
<%= render 'parties/party', :object => party %>
</div>
<% end %>
And this is the code in the partial:
<%= party.name %>
However, I get the following error:
undefined method `name' for nil:NilClass
I'm at my wits end, someone please help :-|
Also, this is the code for the controller to render the view containing the partial (The controller's called default_controller):
def index
#parties = Party.all
end
Is it of any consequence that this isn't the parties_controller?

I've tried something like below and it worked
<%= render :partial => 'party', :object => party %>
and I can access like party.name. the local variable is named after the partial name which is party here.
Note: Im assuming that your both partials are of parties_controller. So this should work.
Update:
Here is what ive tried with again
class PostsController < ApplicationController
#... ...
def index
#posts = Post.all
#comments = Comment.all #<---- Loading comments from PostsController
#... ...
end
end
#views/posts/index.html.erb
<% #comments.each do |comment| %>
<%= render :partial=>"comments/comment", :object=>comment %>
<% end %>
#views/comments/_comment.html.erb
<%= comment.body %>
And its working :)

Related

How to pass nested resource to custom helper for ruby on rails?

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

undefined method `each' for nil:NilClass while attempting to use a partial

I'm currently having the issue for when I try to use a partial inside of invoices/_form.html.erb, it goes into parts/_index.html.erb and breaks.
Inside of the parts_controller I have:
def _index
#parts = Part.all
end
#unsure if this is needed
Inside of invoices_controller I have:`
def new
#invoice = Invoice.new
#parts = Part.all
end`
Inside of invoices/_form.html.erb I have:
<%= render :partial => "parts/index" , :part => #parts %>
And inside of invoices/new.html.erb I have:
<h1 style="padding-left:120px">New Invoice</h1>
<%= render 'form', invoice: #invoice, part: #parts %>
<%= link_to 'Back', invoices_path, class: "btn btn-default col-md-2" %>
So what this code is attempting to do is display the index page of parts so the user is able to see all current parts they have in stock, and how many of that part is in stock. The parts/index page is the exact same as the the default index page for parts, but it just has a link removed.
The line of code that gives me an issue in parts/index is:
<% #parts.each do |part| %>
And what's confusing me about that is that I should be passing it an object that has data inside of it, since it's declared in both the controller for parts, and the invoice controller. Am I missing something super simple with my syntax, or is what I'm trying to do not the right way to do it? I'm still a noob to rails, so sorry if what I'm trying to get across doesn't make too much sense.
so here is the problem:
<%= render :partial => "parts/index" , :part => #parts %>
you are sending :part to your _index.html.erb partial while using #parts
you need to update your render call to following:
<%= render :partial => "parts/index" , locals: {parts: #parts}%>
and your loop to:
<% parts.each do |part| %>
you provide to _index.html.erb variable part but try to render #parts.
1. you don't need method _index, when your patial _index.html.erb render that not get variable #parts from method _index. I think it's wrong.
2. You need to render in _index.html.erb variable which it's provided from _form
<% part.each do |part_| %>

rails partial passing param got empty variable

I try to pass a param to a partial in view
controller
def addMovie
#movies = Movie.all
#vid = Movie.new
end
view
<%= render partial: "shared/videoList", videoList: :movies %>
partial
stored in app/views/sharead
<% if #videoList.present? %>
<% #videoList.each do |movie| %>
videoList is empty ... why?
Access the variable using videoList and not #videoList,
<% if videoList.present? %>
<% videoList.each do |movie| %>
also, you need to pass the variable like this
<%= render 'shared/videoList', videoList: #movies %>
Hope that helps!

Rendering a partial in rails. Specifying the partial for a resource gives an error, but not specifying a partial works fine. What gives?

I've got this working now quite accidentally, but I don't understand what causes it to break when I explicitly specify what partials are to be used for rendering the resource/s. Can anyone explain it?
The index template for my Posts controller contained the following line, which was giving me an error:
<%= render partial: 'posts', collection: #posts %>
The error (in my browser) said:
NoMethodError in Posts#index
Showing /Users/applebum/Sites/rails_projects/eventful2/app/views/posts/_posts.html.erb where line #1 raised:
undefined method `any?' for #<Post:0x000001064b21f0>
Extracted source (around line #1):
1: <% if posts.any? %>
2: <div id="posts">
3: <% posts.each do |post| %>
4: <%= render partial: "posts/post", locals: { post: post } %>
Changing the problem line to
<%= render #posts %>
made the error disappear and the posts appear (displayed nicely in markup from the appropriate partials) as I had wanted and expected them to.
Here's my _posts.html.erb partial:
<% if posts.any? %>
<div id="posts">
<% posts.each do |post| %>
<%= render partial: "posts/post", locals: { post: post } %>
<% # render :partial => "comments/comments", :collection => post.comments %>
<% end %>
</div>
<% end %>
And the _post.html.erb partial it's referring to, if that matters:
<div class="post" id="post_<%= "#{post.id}" %>">
<div class="post_inner">
<%= link_to avatar_for(post.user, size: "small"), post.user.profile %>
<div class="post_body">
<div class="user-tools">
<% if can? :destroy, post %>
<%= link_to '<i class="fi-x"></i>'.html_safe, post, :method => :delete, remote: true, :class => "delete", :confirm => "Are you sure you want to delete this post?", :title => post.content %>
<% end %>
</div>
<h5 class="username">
<%= link_to post.user.name, post.user.profile %>
<span class="timestamp">• <%= time_ago_in_words(post.created_at) %> ago</span>
</h5>
<div class="content">
<%= post.content %>
</div>
<ul class="foot">
<li>Like<li>
<li>Share</li>
</ul>
</div>
</div>
</div>
And the relevant bits from the controller:
class PostsController < ApplicationController
respond_to :html, :js # Allow for AJAX requests as well as HTML ones.
before_filter :load_postable
load_and_authorize_resource
def index
#post = Post.new
#posts = #postable.posts
end
private #################
def load_postable
klass = [User, Event].detect { |c| params["#{c.name.underscore}_id"] } # Look for which one of these there's a ***_id parameter name for
#postable = klass.find(params["#{klass.name.underscore}_id"]) # Call find on that, passing in that parameter. eg Event.find(1)
end
Can anyone explain to me what's going on here? I couldn't find anything in the Layouts and Rendering guide at rubyonrails.org.
Thanks!
Your error comes from assuming :collection and #posts mean the same thing when rendering. From Rails Docs (point 3.4.5):
Partials are very useful in rendering collections. When you pass a collection to a partial via the :collection option, the partial will be inserted once for each member in the collection
So, if you use that, for each post, you will be doing post.any? which fails as any? isn't defined for a single post.
From the same docs, you should check if render returns Nil to see if the collection is empty:
<h1>Posts</h1>
<%= render(#posts) || "There are no posts." %>
PD: Use the partial to render only one post, not all of them.
GL & HF.

Call a controller method automatically when rendering a partial

I have a partial that needs to have some controller logic run before it can render without issue. Is there some way to associate the partial with some controller logic that is run whenever it is rendered?
For example, this is what my current code looks like:
MyDataController:
class MyDataController < ApplicationController
def view
#obj = MyData.find(params[:id])
run_logic_for_partial
end
def some_method_i_dont_know_about
#obj = MyData.find(params[:id])
# Doesn't call run_logic_for_partial
end
def run_logic_for_partial
#important_hash = {}
for item in #obj.internal_array
#important_hash[item] = "Important value"
end
end
end
view.html.erb:
Name: <%= #obj.name %>
Date: <%= #obj.date %>
<%= render :partial => "my_partial" %>
some_method_i_dont_know_about.html.erb:
Name: <%= #obj.name %>
User: <%= #obj.user %>
<%# This will fail because #important_hash isn't initialized %>
<%= render :partial => "my_partial" %>
_my_partial.html.erb:
<% for item in #obj.internal_array %>
<%= item.to_s %>: <%= #important_hash[item] %>
<% end %>
How can I make sure that run_logic_for_partial is called whenever _my_partial.html.erb is rendered, even if the method isn't explicitly called from the controller? If I can't, are there any common patterns used in Rails to deal with these kinds of situations?
You should be using a views helper for this sort of logic. If you generated your resource using rails generate, a helper file for your resource should already be in your app/helpers directory. Otherwise, you can create it yourself:
# app/helpers/my_data.rb
module MyDataHelper
def run_logic_for_partial(obj)
important_hash = {}
for item in obj.internal_array
important_hash[item] = "Important value" // you'll need to modify this keying to suit your purposes
end
important_hash
end
end
Then, in your partial, pass the object you want to operate on to your helper:
# _my_partial.html.erb
<% important_hash = run_logic_for_partial(#obj) %>
<% for item in important_hash %>
<%= item.to_s %>: <%= important_hash[item] %>
<% end %>
Or:
# app/helpers/my_data.rb
module MyDataHelper
def run_logic_for_partial(item)
# Do your logic
"Important value"
end
end
# _my_partial.html.erb
<% for item in #obj.internal_array %>
<%= item.to_s %>: <%= run_logic_for_partial(item) %>
<% end %>
EDIT:
As commented Ian Kennedy points out, this logic can also reasonably be abstracted into a convenience method in your model:
# app/models/obj.rb
def important_hash
hash = {}
for item in internal_array
important_hash[item] = "Important value"
end
hash
end
Then, you'd access the important_hash attribute in the following manner in your partial:
# _my_partial.html.erb
<% for item in #obj.important_hash %>
<%= item.to_s %>: <%= item %>
<% end %>
What you're trying to do runs against the grain of how Rails controllers/views are designed to be used. It would be better to structure things a bit differently. Why not put run_logic_for_partial into a helper, and make it take an argument (rather than implicitly working on #obj)?
To see an example of a view "helper", look here: http://guides.rubyonrails.org/getting_started.html#view-helpers

Resources