Correctly generate a form builder object while discarding the HTML without a deprecation warning - ruby-on-rails-3

I have a partial which generates a div with some form fields in it. It uses the form builder variable "f" which is provided as input to correctly name the fields in the parameter has (fields are actually nested attributes, so the name is like "[author][book][0][title]").
I want to use that same partial when receiving an AJAX call to regenerate the div based on new user information. I am currently using <% form_for ... |f| %> in my erb file, but that generates a warning that "<% %>" is deprecated.
My erb file looks like the following:
<% if f.nil? %>
<% form_for(#author, :id => :coupon_form) do |f| %>
<%= render "books_detail1", :f => f %>
<% end %>
<% else %>
<%= render "books_detail1", :f => f %>
<% end %>
So what is the correct way to create a form builder context while discarding the generated HTML?

The correct answer is to use fields_for. It generates the same form builder object without the html. I lost track of this in it's use for sub-forms, but it's really the same thing.

Related

In Rails 3 how does the simple_form_for method know whether to include the params[:id] in the action attribute?

I'm new to rails, and I'm trying to figure out how to make the [action] attribute on a form dynamic so that I can reuse the form markup.
In MVC.net it's easy as you usually specify the :controller and :action.
However in rails there's just a "simple_form_for(#my_model)" method.
If I browse to /my_models/new the action attribute is:
action = "/my_models"
But if I go to /my_models/1/edit the action attribute is:
action = "my_models/1"
What if I want to create a new action for handling POSTs of my_model AND still reuse the same _form.html.erb... how does that work?
I think it's actually rails doing this
https://github.com/rails/rails/blob/master/actionpack/lib/action_view/helpers/form_helper.rb#L230
In short it just infers the url based on the resource and whether it is new or an existing one.
SimpleForm's FormBuilder is inherited from ActionView::Helpers::FormBuilder
You can check out that code https://github.com/plataformatec/simple_form/blob/master/lib/simple_form/form_builder.rb
I guess I'm not understanding the last part. Say you wanted to use a custom action instead of the inferred ones you could just make a partial of the form elements and use that partial for all forms.
so _form.html.erb
<%= simple_form_for #my_object do |f| %>
<%= render 'form_elements' %>
<% end %>
_custom_form.html.erb
<%= simple_form_for #my_object, :url => custom_url do |f| %>
<%= render 'form_elements' %>
<% end %>
_form_elements.html.erb
form elements as usual

partial local only accessible using local_assigns, not exposed by name

I am passing two locals from a view ERB to a partial. Both locals are successfully passed in local_assigns. However, I am only able to use the FormBuilder via a local variable name in the partial. The other value is usable within my partial as local_assigns[:disable_edits], but not as disable_edits.
_form.html.erb
<div>
<%= f.fields_for :panels do |builder| %>
<%= render "panel_fields", :f => builder, :disable_edits => true %>
<% end %>
</div>
_panel_fields.html.erb
<div>
<p>
<%= local_assigns[:disable_edits] %>
</p>
<p>
<%#= disable_edits ? 'disable edits true' : 'disable edits false' %>
</p>
<p>
<%= local_assigns.keys %>
</p>
local_assigns[:disable_edits] results in "true" being displayed.
local_assigns.keys results in "[:f, :disable_edits, :panel_fields]" being displayed.
Uncommenting the ternary statement results in "undefined local variable or method `disable_edits' for #<#:0x4d58768>"
I am following what I understand is the latest suggested Rails syntax, but have tried manipulations using :partial=>, :locals=>, :as=>, etc. to no avail. I also do not think I've made this an optional argument in any way, so a lot of the information about testing with has_key vs. nil? isn't helping me. My understanding is everything in local_assigns should be exposed as in the partial as a local variable with the same name as the hash key.
I'm getting by for now using local_assigns[:disable_edits], but would like to understand what is happening and correct things so I can use more conventional syntax. Thanks!
try using
render :partial => "panel_fields", :locals => {:f => builder, :disable_edits => true }

rails render model with location

I have a Picture model and i'd like to use <%= render #pictures %> in my view in order to display them.
I also want the pictures to be arranged as 3 columns across the screen.
If I use the render how can I know which picture I am rendering in order to know where to place it? (such as in a table or some other arrangement that is not 1 dimensional)
Is there a way to make the rendering automation to have a counter?
<% #pictures.each_index do |i| %>
<% #some routine here %>
<%= render #pictures[i] %>
<% end %>
I would suggest using each_with_index instead:
<% #pictures.each_with_index do |picture, i| %>
<%= render picture, :i => i %>
<% end %>
Notice that you can pass index to the partial as well.

Why is my nested text_area helper adding html tags?

I have a text_area in a partial in a complex form that is called like so
<%= f.fields_for :notes do |notes_form| %>
<%= render :partial => 'note', :locals => {:f => notes_form, :operation => f, :count => operation.notes.count} %>
<% end %>
<p><%= add_child_link "Add note", :operation_notes %></p>
and the partial looks like this
<% count ||= 2 %>
<div class='fields'>
<%= f.text_area :note_text, :rows => "4", :class => "notes" %>
<%= remove_child_link "x", f, count %>
</div>
There can be many notes on the form hence the add and remove child links.
The issue I'm having is that if I add a note with the text 'abcd', when I bring up the edit form I get '<p>abcd</p>'. If there are line breaks in the note it adds <br /> tags. The text_area form helper seems to be using the simple_format helper but I have no idea why. Can anyone help as this is very undesirable behaviour?
Ah solved,
Earlier on the same page I was displaying the note and using simple_format to format it with
<%= simple_format note.note_text %>
It seems that simple_format is somewhat destructive as after this, a call to note.note_text always returns the formatted text. If I change the above to
<%= simple_format note.note_text.dup %>
then the note_text attribute is not altered and I get the appropriate results.
I will have to look more closely at simple_format but this really strikes me as undesirable behaviour.
EDIT
It looks like this has been corrected in Rails 3.1
I would suspect that you have something in your Note model that is processing the text. Check for callbacks in this model.

Is it possible to use partials to be rendered as wrappers in Rails?

I would like to render structures like this:
<tag1>
<tag2 someattribute="somevalue">
<.. lot of things inside ..>
</tag2>
</tag1>
<tag1>
<tag2 someattribute="someothervalue">
<.. different inside things inside ..>
</tag2>
</tag1>
The tag1, tag2 are the same, they are just parametrized. The inner part of the code changes. I tried to implement the thing above like that (haml):
%div{id:['products', id]}
.products_content
%div{id:['products', id, 'content'], class:'products_mask'}
= yield
This was the partial _content_head.html.haml, which is called from a template:
= render 'shared/content_head', id: 'all' do
%h3= Title
%p= Body of the text.
My theory that yield inside the partial would lead to rendering of the passed block did not prove. Is there a way to use partials as code wrappers? Can you suggest me some solution how to reach this? Thank you.
This might be a good use of the capture method.
I'm only familiar with ERB, but here is the general idea:
<% structure = capture do %>
<h3>Title</h3>
<p>Body of text</p>
<% end %>
Then pass the variable into the partial:
<%= render 'shared/content_head', :structure => structure %>
And within the partial, spit out the structure variable:
<%= structure %>
Reset structure multiple times within the view as you render partials (or maybe more appropriately, in a helper?).
I've used the following (Rails 4, but I think it should work with Rails 3 too):
<%# app/views/users/_edit.html.erb %>
<%= render layout: 'modal_wrapping' do |f| %>
<%= f.input :email %>
...
<% end %>
.
<%# app/views/users/_modal_wrapping.html.erb %>
<div id='modal'>
<%= simple_form_for #user do |f| %>
<%= yield f %>
<% end %>
</div>