Question

I know views shouldn't be rendered from a model, but I cannot make sense of a better way to handle this problem.

I have a simple_form form that should show a list of object as checkboxes:

= f.association :results, collection: @search.results.all(order: 'cost'), as: :check_boxes

Like this it would only show the object next to a checkbox, but I need to display a bunch of more detailed information, so I'm defining the to_label method in my model like this:

class Result < ActiveRecord::Base
  belongs_to :search

   def to_label
         "<div class='row'>
            <div class='col-md-2'>#{supplier}</br><span class='label label-default'>#{brand}</span></div>
            <div class='col-md-2'>#{desc}</div>
            <div class='col-md-2'>#{model}</div>
            <div class='col-md-1'>#{season}</div>
            <div class='col-md-1'>#{qty}</div>
            <div class='col-md-1'>#{expected_delivery}</div>
            <div class='col-md-1'>#{msrp}</div>
            <div class='col-md-1'>#{cost}</div>
         </div>".html_safe
   end

end

This shows some better formatted information, but still it's becoming very complicate to mantain and I will need at some point to add information like images etc. Of course it is also very wrong from a MVC point of view.

My idea is to create a partial in app/views, using haml as for the rest of my application and make my to_label method look like this:

def to_label
  render "results/label"
end

Of course rails won't allow me to do that, but I have no better idea on how to implement it.

Was it helpful?

Solution 2

Bending rails that way will get you somewhere you don't wanna be. First of all you trying to render complex html layout by making simple_form thinking it's label for form control. Building custom form without use of simple_form makes more sense. Because rendering simple controls with automatic label generation is kinda simple form thing. And you are way beyond that.

So solution to your problem as it seems for me is defining to_partial_path on your class:

class Result < ActiveRecord::Base
  def to_partial_path
    'results/form'
  end
end

and render your form with:

= render @results

it may be rendered inside of simple form you just need to build form controls with rails or simple form helpers.

OTHER TIPS

You should not access views from a model. Instead, create a helper with a function that receives the result object as a parameter (code not tested):

helpers/results_helper.rb

result_to_label(result)
    render(:template =>"results/label", :layout => nil , :locals => { :result => result }).to_s
end

Then, from your view you call result_to_label(the_result) directly.

Update

In your simple_form, you can add the label_method with a lambda:

= f.association :results, collection: @search.results.all(order: 'cost'), label_method: lambda { |res| result_to_label(res) }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top