You can use local_assigns:
<% form_or_view = local_assigns[:f] || self %>
<%= form_or_view.fields_for object_name, obj do |ff| %>
Question
I want to DRY the code as much as I can, but I think this maybe too dry..
I have a fields_for
partial, that sometimes I need to have it by relation and sometimes fields_for
for the object itself
<%= form_for model_name do |f| %>
<%= render partial: 'fields_for_partial', locals: {f: f, ... } %>
<% end %>
calling the fields_for partial would be different depending on when I need the form - if I want to create a new model I would use the form_for
's f
, but sometimes I want to edit the model and just show a particular nested model, which then I would use fields_for nil, obj
to render the fields for that specific object
I attempted to do this when testing a local variable f
that I am passing
<% if f.nil? %>
<%= fields_for object_name, obj do |ff| %>
<% else %>
<%= f.fields_for object_name, obj do |ff| %>
<% end %>
the rest of the partial would be a regular fields_for
with ff
like
which is obviously a massive fail..
How would I write this kind of code?
Solution
You can use local_assigns:
<% form_or_view = local_assigns[:f] || self %>
<%= form_or_view.fields_for object_name, obj do |ff| %>
OTHER TIPS
move the call to fields_for
outside of the shared partial. Take for example a project and a task. You allow users to create a project and a task at the same time.
# using HAML
# project form
= form_for @project do |f|
= f.fields_for :tasks do |tf|
= render 'tasks/form', f: tf
You also allow users to create only tasks.
# task form
= form_for @task do |f|
= render 'tasks/form', f: f
The tasks/_form.html.haml
partial will look like
# task fields
= f.text_field :title
= f.text_area :description