Draper with form_for in method

848 views Asked by At

I am trying to create a method in a draper decorator that will spit out a form_for. I have a form that i'm using for searching records on the index view and have dozens of resources, so I really want to maintain this logic in one place if possible (application decorator). My problem is that I have no idea how to render a form_for in the decorator. I've come across some uses of concat and capture to try and accomplish this, with no luck. All i've been able to get is a couple of my divs to display (not as html either, just as plain text). Any ideas on how I can do this? This is the code i've got:

def crud_index_search(search_obj)

h.concat "<div id='basic_search' style='display:none;'>"

search_form_for search_obj do |f|
  h.concat '<div class="input-append">'
  f.text_field :name_or_description_cont, :placeholder => 'Quick search ...', :id => 'search'
  h.concat "<button class='btn'><i class='icon-search'></i></button>"
  h.concat '</div>'
  link_to 'Advanced Search', '#', :id => 'advanced_search_btn', :class => 'pull-right'
end

h.concat '</div>'

h.concat "<div id='advanced_search' style='display:none;'>"
search_form_for search_obj do |f|
  f.condition_fields do |c|
    h.concat render "crud/partials/condition_fields", :f => c
  end
  h.concat "<p>#{ link_to_add_fields 'Add Conditions', f, :condition }</p>"
  f.submit 'Search'
  h.concat "#{link_to 'Basic Search', '#', :id => 'basic_search_btn', :class => 'pull-right'}"
end
h.concat '</div>'
end

and in my view...

<%= @categories.crud_index_search @search %>

Any help would be greatly appreciated!

FYI, I've already put this into a partial and that works, however there is some more complex logic I will need to add to this that will make it differ on a per resource basis, so a partial is not ideal for me.

Thanks

1

There are 1 answers

0
Alex Peachey On

Draper is excellent for putting logic pertaining to the view and does well at simple presentation, however you should in principle be leaving the content presentation to the view since that is what it is there for.

A pattern that I recommend is using the method on your Draper object to facilitate the logic and for each logic path render an appropriate partial.

So you might have something like this:

def crud_search_index(search_object)
  if search_object.something_to_check
    h.render 'shared/one_version_of_my_form'
  else
    h.render 'shared/another_version_of_my_form'
  end
end

And, even better, since your form is directly related to that search_object, I would actually create a Draper Decorator for that search object and put the method to generate the form on there instead of an "application" decorator.

Then your view is something like:

<%= @search.form %>

And if you need a reference to the @categories then pass it in to that method.