Rails passing form_for object to partial - ruby-on-rails

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|
...

Related

Render partial with locals inside a form_for tag

I have this form (simplified)
<%= form_for #client do |client| %>
<%= render "some_partial", foo: 10, bar: 20 %>
<% end %>
I also try with: <%= render :partial => "some_partial", :locals => {foo: 10, bar: 20} %>
And in some_partial:
<%= foo %>
<%= bar %>
But, the variables are not available on partial:
undefined local variable or method `foo' for #<#<Class:0x007fb35027bbd0>:0x007fb350536e60>
If I put render out side of form_tag works fine
Thanks in advance
UPDATE1: At the end of form, I have this:
<%= link_to_add_association 'Add', client, :client_addresses, class: "ui mini green button add_client_address" %>
If I remove this part, works fine...
You have to mention parameters as locals, like this.
<%= render :partial => "some_partial", :locals => {foo: 10, bar: 20} %>
Is the "some_partial" the same :client_addresses you are trying to load with the link_to_add_association?
I believe that the error message you are experiencing is coming from within the link_to_add_association
Seems you are using the Cocoon gem. In order to pass locals into the partial that Cocoon uses (:client_addresses in your case) you need to pass the parameter render_options: { locals: {foo: bar} for the link_to_add_association

Rails 3 - Not able to pass local variable to a partial resursively

++ 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?

Why does my render partial call not give me proper access to the local variable?

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 %>

Passing ActionView::Helpers::FormBuilder to a partial

I am atempting to dinamically create form elements given a certain AJAX request.
This is my setup:
View:
<%= link_to 'Next', check_unique_id_students_path, :remote => true %>
<div id="guardian_student_details"></div>
Controller:
def check_unique_id
#student = Student.new
#this_form = ActionView::Helpers::FormBuilder.new(:student, #student, #template, {}, proc{})
end
JS:
jQuery("#guardian_student_details").html("<%=escape_javascript(render :partial => "student_details", :locals => { :s => #this_form }) %>");
Partial:
<% puts s.text_field :first_name %>
<% puts s.field_helpers %>
For debugging purposes i placed the following lines at the very beginning of my partial:
<% puts s.class.to_s %>
<% puts s.object.to_s %>
This prints out :
ActionView::Helpers::FormBuilder
Student
This should work. However rails is giving the following error:
ActionView::Template::Error (undefined method `text_field' for nil:NilClass):
1: <% puts s.class.to_s %>
2: <p>
3: <%= s.text_field :first_name, :class => 'text_input is_empty' %>
4: <%= s.label :first_name %><strong>*</strong>
5: </p>
6:
app/views/students/_student_details.html.erb:3:in _app_views_students__student_details_html_erb__2485891544130782916_2214680440'
app/views/students/check_unique_id.js.erb:2:in_app_views_students_check_unique_id_js_erb__3504800328150418937_2214933160'
Which implies that "s" is NIL something I verified just 2 lines before. Does anybody have any ideas? i dont know if this has something to do with the "#template" variable initialized in the controller. Which i played around with and accepts practically anything and if printed is nil.
Any help would be appreciated. Thanks
Final note:
I tried to implement this: AJAX update of accepts_nested_attributes_for partials
For anyone needing to build a form builder in the controller, view_context still works there. Using Rails 4.1.4:
#object = Object.new
#f = ActionView::Helpers::FormBuilder.new(:object, #object, view_context, {})
In the view, I've found that 'view_context' does not work in Rails 3.1. Instead try 'self' when creating a FormBuilder object.
s = ActionView::Helpers::FormBuilder.new(:student, #student, self, {}, proc{})
Try this in a console :
s = ActionView::Helpers::FormBuilder.new(:student, #student, #template, {}, proc{})
s.text_field :first_name
You will have the same error. I think the problem come from your creation of the form_builder object, even if I don't know the exact mistake...
Your solution seems to me to be a little much complex. You can try this solution :
#html.erb
<% form_for #student do |f| %>
<div id='guardian_student_details' class='hide-this-block'>
<%= render :partial => "student_details", :locals => { :s => f }) %>
</div>
<% end %>
#js
jQuery("#guardian_student_details").show();
Generally, I prefer keep javascript and ruby separated.

Rails partial view set value of form field

Okay so I am quite new to Rails and am trying to do the following without success:
I have an Object (from my Active Record) containing a project, which contains n sub-projects, which contain n tasks. Now for each of these I want a partial view.
So I render from the project view the sub-project with the following code:
<%= render(:partial => 'subproject', :collection => #project.sub_projects) %>
Within my sub-project partial view called _subproject.rhtml (adding the code to a good ol Rails 1.2.3 project), so I can access the data like this:
<%= subproject.name %>
That will print out the name alright but when I try to generate a textfield this won't work:
<%= text_field 'subproject', 'name' %>
But this will:
<%= text_field 'subproject', 'name', :value => subproject.name %>
What am I doing wrong?
Edit: Changed title due to my problem is not passing the value but displaying it within a form field.
Edit2: As requested my controller code:
#project = Project.find(params[:id])
You can write this:
<%= render(:partial => 'subproject', :collection => #project.sub_projects) %>
as
<%= render :partial => #project.sub_projects %>
This will render every sub project with the sub_projects/_sub_project.html.erb partial. A little shortcut.
This:
<%= text_field 'subproject', 'name' %>
Says create a text_field called: subproject[name], but doesn't give it a value. You need to pass the value you want to set (the code that works).
The more idiomatic way of doing this now is with form_for:
<% form_for #subproject do |f| %>
<%= f.text_field :name %>
<% end %>
Or if you're using formtastic (https://github.com/justinfrench/formtastic), which is fantastic, you'd write:
<% semantic_form_for #subproject do |f| %>
<%= f.input :name %>
<% end %>
I hope this helps!

Resources