DEV Community

n350071🇯🇵
n350071🇯🇵

Posted on

[Rails] Getting polymorphic models with human name for view

Model

class Contracts::Rental < ApplicationRecord
  belongs_to :tenant, polymorphic: true # User, Company
  belongs_to :landlord, class_name: 'Company'
  belongs_to :agency, class_name: 'Company'
  belongs_to :property, polymorphic: true # Properties::Building, Unit, Room

  class << self
    def property_types
      [Properties::Building, Properties::Unit, Properties::Room]
    end
  end
end

I18n

Helper

module Contracts::RentalsHelper
  # => [["Building", "Properties::Building"], ["Unit", "Properties::Unit"], ["Room", "Properties::Room"]]
  def property_type_names
    [Contracts::Rental.property_types.map(&:model_name).map(&:human), Contracts::Rental.property_types.map(&:to_s)].transpose
  end
end

View

  <div class="field">
    <%= form.label 'Property Type' %>
    <%= form.select(:property_type, options_for_select(property_type_names, selected: contracts_rental.property_type)) %>
  </div>

Top comments (4)

Collapse
 
mikerogers0 profile image
Mike Rogers ✈️

This is kind of a cool problem to solve!

What are your thoughts about moving your helper method onto the model?

Collapse
 
n350071 profile image
n350071🇯🇵

Thanks!

I've intended the code for the view and I heard that it should be put into the helper if it's for the view. So, this is why I put it in helper.
How do you think about it?

Collapse
 
mikerogers0 profile image
Mike Rogers ✈️ • Edited

I've stopped using Helpers. What would find was a method would be named with the intension it was used in a single view scope (e.g. within app/views/users), then as it was available everywhere it would be reused without making the method name more explicit.

Instead I've opted for either model decorators, or the collection_select helper e.g:

<%= form.collection_select(:property_type, Contracts::Rental.property_types, :to_s, :model_name) %>
Thread Thread
 
n350071 profile image
n350071🇯🇵

LGTM!! It's a better way. Thank you.