2

I plan to insert a two-dimensional array into the database with ActiveRecord.

The reason why: I want users to select multiple languages and the corresponding language-levels (like how good they speak it). I do not want to have two fields for both languages & language_levels, I want those two to be hooked together from the beginning. Sure, I could hook them together later on the model level, but I want to try it the other way first.

Example:

[ ["English",2],  ["German",1], ["Japanese",1] ]

I've been able to store one-dimensional arrays, though had no luck with these. Trying to make those accessible using something like (languages: [][]) in the strong parameters didn't work.

Thanks

3
  • Just out of curiosity: have you tried using hashes for that? Commented Jan 4, 2014 at 15:36
  • No I haven't :P Going for Dannys suggestiion Commented Jan 4, 2014 at 16:01
  • 2
    This is an awful idea -- there's a reason for database normalisation, you know. How is your query for "All users who speak English at level 2 or above" going to look? How will you ensure data integrity? Commented Jan 4, 2014 at 16:10

2 Answers 2

2

I understand your intent to do this with sort of minimal effort, but you should definitely consider looking into storing things the normalized way.

The intention is – what to do with lang. skills for all your users, once there's a need to rename a language? Say you had Chinese language as of the start, but then you've decided to keep two of them, Chinese (traditional) and Chinese (simplified). You'd now have to write an error-prone update script.

In case of keeping the languages normalized way, I'd keep three models for consistency:

class User < ActiveRecord::Base
  has_many :language_skills
  has_many :languages, through: :language_skills
end

class Language < ActiveRecord::Base
  has_many :language_skills
  has_many :users, through: :language_skills
end

class LanguageSkill < ActiveRecord::Base
  belongs_to :user
  belongs_to :language
end
Sign up to request clarification or add additional context in comments.

6 Comments

Pro: keeps your database "clean" in that the user can only select languages from a predefined list. (although you can also do that when you keep the language as a string) Contra: who will add the "new" languages? The administrator or the user himself? What if the user wants to add some "weird" language the administrator didn't think about?
You're right. In that moment I didn't realize I was about to mess up my database :-) Anyhow am I right you intended to have a one-to-many-relationship between the Language and LanguageSkills? I worried the most about what data is getting stored in my database and actually thought it's going to look awful, though I was totally wrong
@JustBasti this is in fact a many-to-many relationship between users and languages, where LanguageSkill represents a join table in the DB
@DannyVanHoof the con of adding the new languages is no worse with this method than it is with storing the languages as a string, though.
If this is supposed to be a many-to-many with a join table, shouldn't you use has_many :languages, through: :language_skill?
|
2

I would definitely go for something like

User
 has_many languages_skills

LanguageSkill
  belongs_to User

  language: string
  level: integer

Then use nested forms to add everything together

I would NOT use multi-dimensional arrays

4 Comments

Sure ... actually thought about making two additional models for either Language AND Skill, but didn't even came near your conclusion ... :D
I'd be adding another model for languages as well, I think.
I would not do that. I would like to refer you to the book "Rails anti-patterns", section "AntiPattern: The Million-Model March", in which they discuss this dilemma. Look at books.google.be/… page 79
The "ideal" way for me would be to offer the user a list of "common" languages, and the "other" selection + a field where he can enter his "other language". That's the approach described in the book

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.