Search code examples
ruby-on-railsruby-on-rails-3.2rails-migrationsmodel-associationsrails-models

Rails user profile devise :has_many or :has_many_through relationships


I'm wracking my brain about how to start setting up the following set of model relationships in my project. I'm not looking for the complete solution (models, tables, migrations, etc), just a little help to get me going in the right direction. I learn more by struggling on my own :)

In short, I want my Users (created with Devise) to have a set of Inclinations that represent preferences they have to certain things (i.e. warmer weather vs colder weather, watching sports vs playing sports, etc) on a sliding scale (coded 5 to -5, zero excluded). Each Inclination (or InclinationData?) will be in a separate table with a name, description, etc, and all Inclinations will get their data pulled from that table (so I don't repeat myself throughout my application). Also, every User will have one Inclination record for each InclinationData(?) by default.

As for the setup, will I need:

  • 5 tables (3 main ones and two join tables)?
  • Just three (main three models)?
  • Four (main three models & a joining table for Inclinations and InclinationData)?
  • Four (main three models & a joining table for Users & Inclinations)?
  • Perhaps something simpler like a single Profile or Preferences model that's bound to a User?

I can never figure out how to decide if joining tables are necessary, and this is the most complex association I've ever tried.

I appreciate any help, and please let me know if you need more information to be able to help me out.


Solution

  • You say, all Users have the same set of Inclinations. You can put the description of the Inclinations in one model/table and the users ratings in the joining table UserInclination , according to eabraham:

    class User < ActiveRecord::Base
      has_many :users_inclinations
      has_many :inclinations, through: :users_inclinations
    
    end
    
    class UsersInclination < ActiveRecord::Base
      belongs_to :users
      belongs_to :inclinations
    
      attr_accessible :user_id, :inclination_id, preference_score
    end
    
    class Inclination < ActiveRecord::Base
       has_many :users_inclinations
    
       attr_accessible :description, :name, :low_label, :high_label
    end
    

    So you can pull the description (i.e. to build the rating form) from Inclinations and store the individual ratings with

    an_inclination= Inclination.find_by_name('weather')
    user.user_inclination.create(inclination: an_inclination, preference_score: the_users_score)