0

I'm considering using single table inheritance for my contacts model in order to implement different behaviour for different kinds of contacts. As I understand it Rails determines which model.rb, controllers, routes and so on to use by looking at the value of the type column in contact.rb.

I intend to use a single create form for contacts where users can select the type of contact in a select box. But how would this work if my default application language is german? So instead of selecting a contact type like "customer", users will select "Kunde" - however of course I don't want to mess up my filenames and would like to use customer.rb, customers_controller.rb, customer_path and so on.

While I understand that you can kind of hide this problem by using german names and english values in the form's select box, it will be an issue as soon as I want to display the value anywhere else, where it needs to be german.

Am I missing something is or STI just not worth the effort if your app is not english?

Michael Feihstel
  • 1,030
  • 1
  • 9
  • 11
  • I've never had any issues with STI in non-English apps. I recommend that you keep the code in English, including model and field names, and then use the I18n framework for the translations into German. The code is easier to read when it's all English, and it enables you to make full use of the conventions that Rails come with. – Arctodus Jul 04 '14 at 06:51
  • While that is a good suggestion (to use I18n) in general, it does not really apply to this case. You are not translating words in templates for other words in templates -- a good use case for I18n. This problem exists with or without german in the equation. – nort Jul 04 '14 at 07:02
  • @Sharagoz Of course I intend to keep my code in english for the reasons you already mentioned. However I think the question I asked becomes important when non-english user input is used to define the model structure/relations as in this case where the value of the type column will likely be non-english term. And now I wonder how to tell Rails that a type of "Kunde" belongs to the customer model. – Michael Feihstel Jul 04 '14 at 08:27
  • The actual model names are stored in the `type` column that rails uses to keep track of the STI. If the model names are in English then those values will also be English. – Arctodus Jul 04 '14 at 08:44
  • I understand that and was wondering if there's another way to tell Rails which models to use. As it seems though this is not the case. I guess I'll just use some kind of type_display method that maps the english values to the german terms. – Michael Feihstel Jul 04 '14 at 09:08
  • 1
    You can translate the model names for STI models just like any other model. If you translate "Customer" into "Kunde" with I18n, then calling `Customer.model_name.human` will return "Kunde". I suggest you try your hand at implementing it and then ask questions on SO when you actually run into problems. It might be easier than you think. – Arctodus Jul 04 '14 at 09:56

1 Answers1

1

I seems like what you need is some translation layer from items in the select to kinds (types) of contacts in the database. I would not suggest allowing the user to select the literal class name from the dropdown but instead have a mapping from select value to class name. This mapping can exist anywhere that makes sense but one way is to have it in the controller

class ContactsController < ApplicationController
  before_filter :translate, only: :create

  def create
    @contact = @translated.create(params[:contact].permit(:name, :starting_date))

    respond_with @contact
  end

  def translate
    mapping = {'Kunde', => Customer, 'Besteller' => Purchaser}

    render_error unless (@translated = mapping[params[:type]]).present?
  end
end

Here we support two possible translation from Kunde to Customer and Besteller to Purchaser, otherwise it is an error

nort
  • 1,625
  • 13
  • 12
  • I'm trying to follow your suggestions, but have a few questions: Which value is saved in the type column? I assume the english term, while the german is only used in the select box, right? If so isn't it a) very similar to the strategy of using different name/value attributes for the select options and b) wouldn't I have to deal with some form of translation/i18n in all views that dispaly the type column? That seems rather complicated, I'd prefer to have "Kunde" as actual value in the column and yet let Rails know to use the customer model. Sorry, if I misunderstood you - I'm new to Rails. – Michael Feihstel Jul 04 '14 at 08:38
  • It won't be the english term nor the german term but the class name of the item, in this case would be `Customer` or `Purchaser`. Internally rails will take the value in the type column and run the `constantize` method on it and return that class as the result. – nort Jul 05 '14 at 03:46