++ edited to change the question to call partial recursively ++
I am writing this question after a lot of days of frustration about this simple piece of code which isn't working. I have read numerous issues with passing partials on stackoverflow and tried all the solutions I could but it doesn't work.
Calling the partial works for the first loop but from second onwards it bombs with an error
"undefined local variable or method `count' for #<#:0x2f12670>"
Notice here that the error contains a class within a class, so something fishy is happening when the partial is being called recursively.
I have a partial called _form.html.erb which calls another partial _rule_action_fields.html.erb. I need to pass a variable from the form partial to the rule_action_field partial and here is the code:
_form.html.erb: (Please note that the builder object here is being passed from code I have not pasted)
<% #folder_count = 1 %>
<% #rule.rule_actions.each do |ruleaction| %>
<%= f.fields_for :rule_actions, ruleaction do |builder| %>
<%= render( :partial => 'rule_action_fields', :locals => { :f => builder, :count => #folder_count } ) %>
<% end %>
<% #folder_count = #folder_count + 1 %>
<% end %>
_rule_action_fields.html.erb
<p id="folder_fields">
<%= count %>
<label class="form_label">Move the files to </label>
<%= f.select(:folder_id, current_user.folders.collect { |p| [p.name,p.id] }, {:include_blank => true } ) %>
</p>
Unfortunately I cant call this partial with a collection of rule_actions because of some logic which is partially in the calling code and partially in the rule_action_fields partial.
Other syntax I have tried:
<%= render :partial => 'rule_action_fields',:f => builder, :locals => { :count => folder_count } %>
<%= render :partial => 'rule_action_fields', locals => { :count => folder_count } %>
<%= render 'rule_action_fields', :count => folder_count %>
Any ideas?
Related
I've got a problem to get my partial working.
I want to pass an object via a local variable to a partial, but I get a
undefined method `model_name' for NilClass:Class
error all the time. But the variable is passed over because I can call it in the partial with .to_yaml, which gives me all the variables properties.
But when I try to use it in a form_for I get that error.
Maybe it has something to do with my db query. Because when i try to call it with another local variable there is no error. But my query should produce a single object, or am I wrong with that?
Here is my show.html.erb:
<%= #partneroffer = Partneroffer.where(:partner_id => #partner.id, :yearname_id => year.id).first %>
<%= render :partial => "form2", :locals => { :partneroffer => #partneroffer } %>
And here is my partial (_form2.html.erb):
<%= form_for partneroffer , :html => { :class => 'form-horizontal' } do |f| %>
<%= f.label :partnerstatus_id, :class => 'control-label' %>
<%= f.collection_select(:partnerstatus_id, Partnerstatus.all, :id, :name) %>
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
partner_year_terms_path, :class => 'btn' %>
<% end %>
It could be that in your partial, partneroffer is a nil object, so it doesn't have the method "model_name".
You are rendering the view the right way, and you are passing the locals the right way, however, are you sure that Partneroffer.where(:partner_id => #partner.id, :yearname_id => year.id).first is not getting a nil value? Try this code in show.html.erb:
<%- #partneroffer = Partneroffer.where(:partner_id => #partner.id, :yearname_id => year.id).first %>
<%- if #partneroffer %>
<%= render :partial => "form2", :locals => { :partneroffer => #partneroffer } %>
<%- else %>
#partneroffer is nil!!!!
<%- end %>
I've found the solution based on one of the related topics (Render :partial a random object from DB by id, in custom form)! The problem was that I have to call the partial four times. But in only one case there was a record in my query results. Each time there wasn't a record rails threw this error message. I knew there was at least a result in one of the partial calls but wasn't aware that there has to be one in each result. Thx to weexpectedthis!
I have a form in a partial that renders three times (for the same three fields). However, the placeholder value for each field should ideally be different. Therefore, I'm trying to pass in a local variable that will change for each rendering of the partial.
In the controller, I created an array like this
#placeholder = %w[ firstplaceholder, secondplaceholder, thirdplaceholder]
I then tried to loop through the array while rendering the partial
<%= f.fields_for :answers do |builder| %>
<% #placeholder.each do |k, arrayindex| %>
arrayindex = #placeholder.index(k)
<%= render :partial => 'answer_fields', :locals => { :f => builder, :myplaceholder => #placeholder[arrayindex] } %>
<% end %>
<% end %>
Passing the arrayindex to the #placeholder generates this error
no implicit conversion from nil to integer
So I'm guessing that arrayindex variable is 'nil'. Why?
Inside the partial, in situation where there are error messages and form fields are repopulated, there won't be placeholders (the #placeholder instance variable only gets created in the controller if there's no errors), so I first check if the #placeholder instance variable is present, and try to set the placeholder to the index created in the loop, however, because of the error passing the arrayindex in, it's not working. There may be other problems :)
<% if #placeholder ? myplaceholder = #placeholder[arrayindex] : myplaceholder = "answer choice" %>
<%= f.text_field :content, :class => 'span3', :rows => 1, :placeholder => myplaceholder %>
<%= f.label :correctanswer, "Correct?" %>
<%= f.check_box :correctanswer, :class => 'span1' %>
<% end %>
Update
In the controller, I'm building three answer fields for the question model. The partial therefore is getting rendered three times automatically because of this. If I loop through the #placeholder array wrapped around the partial, it's rendering the partial that many more times 3 * 3.
3.times {#question.answers.build}
First, note that you don't need the comma separators here:
#placeholder = %w[ firstplaceholder secondplaceholder thirdplaceholder]
And you don't need to use the index into the array (if I understand what you're trying to do). So it should be as simple as:
<%= f.fields_for :answers do |builder| %>
<% #placeholder.each do |k| %>
<%= render :partial => 'answer_fields', :locals => { :f => builder, :myplaceholder => k } %>
<% end %>
<% end %>
In the controller, along with the array of placeholder values, I did
#i = 0
The forms_for partial was being rendered 4 times because I created 4 answers.
4.times { #question.answers.build}
Therefore, after each rendering of the partial, I incremented the #i instance variable and passed the incremented value into the #placeholder array #placeholder[#i] and inside the partial used the appropriate element of the array
<%= f.fields_for :kanswers do |builder| %>
<%= render :partial => 'kanswer_fields', :locals => { :f => builder, :k => #placeholder[#i]} %>
<% #i += 1 %>
<% end %>
On my Home#Index page, I have this:
<%= render 'home/popular_products', :collection => #products, :as => :product %>
In my Home#_popular_products view, I have this:
<div class="span2 recommended">
<%= image_tag product.image_url(:thumb).to_s %>
</div>
This is the error I keep getting:
undefined local variable or method `product' for #<#<Class:0x007f871c4f6848>:0x007f871cdb7e28>
As far as I understand it, I shouldn't even have to specify the :as attribute in my render statement - but I tried this to be explicit after just using the :collection => #products wouldn't work.
In my Home#Index Controller I have this:
#products = Product.all.sample(6)
Thoughts?
I believe you have to specify the :partial option if you want to pass in any other options. Ie:
<%= render :partial => 'home/popular_products', :collection => #products, :as => :product %>
Should work.
Do you put _popular_products.html.erb file in your app/views/home/? I think you're using partial not following convention of rails, so rails's not understood product variable. Your partial should be named _product.html.erb if you want to used like that. With that partial, you can write like this:
<%= render #products %>
Update
Solution 1
Index page:
<%= render 'popular_products', :collection => #products %>
Partial:
<%= image_tag popular_products.image_url(:thumb).to_s %>
Solution 2
Index page:
<% #products.each do |product| %>
<%= render :partial => "popular_products", :locals => { :product => product } %>
<% end %>
Partial:
<%= image_tag product.image_url(:thumb).to_s %>
I would like to pass the form_for object to a partial:
<%= form_for #price do |f| %>
...
<%= render :partial => "price_page", :object => #price, :as => :f %>
...
<% end %>
When I call:
f.radio_button
Brings the error:
undefined method `radio_button' for #<Price:0x3cb1ed0>
How can I use f as I usually would in this partial?
Try passing form object as local
<%= render :partial => "price_page", :locals=>{:f=>f} %>
You can pass form builder object as a local variable like below,
<%= form_for #price do |f| %>
<%= render :partial => "price_page", :locals => { :f => f } %>
<% end %>
in your partial file you will be receiving form builder as a local variable "f", you can use like below,
<% f.radio_button, {} %>
I ran across this question trying to figure out how to get a form builder into a partial without an additional form tag. That's the primary use case I could think of for this question, so I'm adding this answer for future visitors.
To solve my problem, I have my form_for in my layout and I render my partial passing only the model. In my partial I use fields_for.
Looks (something) like this:
= form_for #price do |f|
...
= render partial: "price_page", object: #price, as: 'price %>
...
Then, my partial has this:
= fields_for price do |f|
...
I have some unexpected behavior in a partial, which is rendered 9 times in users/show.html.erb. (Visit www.nowdoing.com/users/2 to see what I mean.) Here is the relevant part of the partial (it's verbose for debugging purposes):
<%= "object 1 = #{object.content}" %>
<div id="float_have" style="display:none;">
<%= "object 2 = #{object.content}" %>
<%= render :partial => 'nowposts/floatpost', :locals => { :object => object.content } %>
</div>
<%= "object 3 = #{object.content}" %>
Have! |
In box #1, :object => "#nowreading book"
In box #2, :object => "#nowlistening song"
Despite this, I'm seeing the following when I load my webpage:
object 1 = "#nowreading book"
object 2 = "#nowreading book"
object 3 = "#nowreading book"
That makes sense for box#1. But the following does NOT make sense for box#2:
object 1 = "#nowlistening song"
object 2 = "#nowreading book" *** this is wrong
object 3 = "#nowlistening song"
Can someone explain to me why including putting the "#{object.content}" within the facebox DIV causes the content to change? I find this behavior very peculiar. Your help is much appreciated!
--- EDIT ---
In users/show.html.erb:
<%= render :partial => 'nowposts/nowpost',
:locals => {:object => #nowreading,
:object_link => #reading_link,
:object_mode => "reading",
:doing_img => #reading_img,
:doing_url => #reading_url_text
} %>
<%= render :partial => 'nowposts/nowpost',
:locals => {:object => #nowlistening,
:object_link => #listening_link,
:object_mode => "listening",
:doing_img => #listening_img,
:doing_url => #listening_url_text
} %>
In nowposts/_nowpost.html.erb:
<div class ="status bl br">
Fresh on <%= object.updated_at.strftime("%b %d, %Y") %><br \>
<% if user_signed_in? %>
<%= "object 1 = #{object.content}" %>
<div id="float_have" style="display:none;">
<%= "object 2 = #{object.content}" %>
<%= render :partial => 'nowposts/floatpost', :locals => { :object => object.content } %>
</div>
<div id="float_wanna" style="display:none;">
<%= "object 3 = #{object.content}" %>
<%= render :partial => 'wishlists/floatpost', :locals => { :object => object.content } %>
</div>
Have! |
Wanna!
<% end %>
</div>
In application.html.erb:
<script type="text/javascript">
jQuery(document).ready(function($) {
$('a[rel*=facebox]').facebox({
loadingImage : '../images/loading.gif',
closeImage : '../images/closelabel.png'
})
})
</script>
The partial nowposts/_floatpoast.html.erb
<h2>Wanna!</h2>
<h3>You wanna do this? Great, put it on your bucket list. </h3>
<%= form_for(:wishlist, :as => #wishlist, :url => {:controller => "wishlists", :action => "create", :user_id => current_user } ) do |f| %>
<p><%= f.label :content %><br />
<%= f.text_field :content, :value => object, :size => "80" %></p>
<p><%= f.submit "Post!" %></p>
<% end %>
As mentioned in my comment below, this code was working in my last commit (a few days ago), before I implemented caching of an API result and these nested routes:
resources :users
resources :nowposts, :only => [:have_create, :create, :new, :show]
end
But I don't think that is the problem. I just ran another test, and object.content only changes when I have it inside this div:
<div id="float_have" style="display:none;">
I tried another random div:
<div id="status">
<%= "object 2 = #{object.content}" %>
</div>
and this displayed correctly. This makes me think that the problem is the Facebox script? But if so, I wonder why it worked a few days ago.
Let me know if you need anything else.
I don't understand your code at all, it is too ambiguous. 'object' is a pretty terrible name for a variable, and content is a really bad name for an attribute. Also, your locals for the partial are rendering here doesn't make much sense ({:object => object.content}????). If you would like help, please try to clarify what this means.
That being said, can you change each debug statement from
<%= "object 1 = #{object.content}" %>
to
<%= "object 1 = #{object.inspect}" %>
<%= "object 1 content = #{object.content.inspect}" %>
and display the results.