Search code examples
ruby-on-railsrails-activerecorddata-modelingmodeling

Rails relationship modelling - quick q. - "Am I doing this right?"


I'm working on an a scavenger hunt app and I'd just like to know if I'm modelling it correctly. There is a list of hunts that users can go on. These hunts are templates that can be customized (e.g. adding/removing certain tasks).

When a user chooses to go on a hunt, I'm calling that a "trip." I've read the Rails Guide on associates and I believe that I should set up the trip model as a join table between users and hunts. Here's what I'm thinking.

    class Users 
      has_many :trips
      has_many :hunts, :through => :trips

    class Hunts
      has_one :trip
      has_many :users, :through => : trips

    class Trip
      belongs_to :users
      belongs_to :hunts

And then the migration where I setup the Trip table would look like this.

    def change
      trip_name
      user_id
      hunt_id
    end

I have two questions.

  1. Does this look right?
  2. Is there a smarter (or more elegant) way to do this?

Update: Here's what I ended up doing.

    class Users 
      has_many :trips
      has_many :hunts, :through => trips

    class Hunts
      has_one :trip
      has_many :users, :through => trips

    class Trip
      belongs_to :hunts
      belongs_to :users

and then

    def change
      create_table :trips do |t|
        t.string :trip_name
        t.references :user
        t.references :hunt
      end
      add_index :trips, :hunt_id
      add_index :trips, :user_id
      add_index :trips, [:hunt_id, :user_id], :unique => true
    end

Solution

  • I see a few small problems:

    1. Models are idiomatically singular: change Users and Hunts unless you have an unusual situation.
    2. A Hunt probably has_many :trips, right?
    3. Your migration is suspiciously sparse. The change method would usually look something like this:

    .

    def change
      create_table :trips do |t|
        t.string :trip_name
        t.references :user
        t.references :hunt
      end
    end
    

    Structurally, what you have makes sense to me.

    Aside: I’ve organised adventures sometimes referred to scavenger hunts, I’m glad I’m not the only programmer doing such things!