user3056783
user3056783

Reputation: 2644

Rails - one table with references to two other tables

I've come up with this table schema for my web app:

+----------+------------+------------+
| User     | Event      | Invitation |
+----------+------------+------------+
| id       | id         | id         |
+----------+------------+------------+
| email    | user_id    | user_id    |
+----------+------------+------------+
| password | start_time | event_id   |
+----------+------------+------------+
|          | end_time   | confirmed  |
+----------+------------+------------+

Those are three models. User can have many events and also many invitations. Event belongs to one user, invitation belongs to one user and one event.

User model

class User < ActiveRecord::Base
  has_many :events
  has_many :invitations
end

Users migration

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :email
      t.string :password
      t.timestamps null: false
    end
  end
end

Event model

class Event < ActiveRecord::Base
  belongs_to :user
end

Event migration

class CreateEvents < ActiveRecord::Migration
  def change
    create_table :events do |t|
      t.references :user
      t.datetime :start
      t.datetime :end
      t.string :description
      t.string :venue

      t.timestamps null: false
    end
  end
end

Invitation model

class Invitation < ActiveRecord::Base
  belongs_to :event
  belongs_to :user
end

Invitation migration

class AlterInvitation < ActiveRecord::Migration
  def change
    create_table :invitations do |t|
      t.references :event
      t.references :user
      t.boolean :confirmed
      t.timestamps null: false
    end
  end
end

Now this is my understanding of Rails so if I'm trying to be too smart and don't follow the conventions, please let me know as I'm sure this is pretty standard schema/model setup.

When I try to do this for example:

u = User.first
u.events.create(start_time:DateTime.now, end_time:DateTime.now + 1)

It all works as expected. user_id is assigned to the user who created it. Now assume we have a user u2 that has sent invitation to attend event e1 I just created above.

e1 = u.events.first
u2.invitations.create(event_id:e1.id, confirmed:false)

When I want to reference the invitations that belong to event e1 it does not work the way I expect it to work:

e1.invitations

NoMethodError: undefined method `invitations' for #<Event:0x007ff214387a08>

I was under the impression that the line belongs_to :event will enable method invitations for me. Can anyone help me out with this? Thank you.

Upvotes: 2

Views: 1432

Answers (2)

Jeremy Anderson
Jeremy Anderson

Reputation: 825

Events should has_many :invitations at the least, if I understand your intentions.

It seems to me at first glance that "u2" is attempting to send an invitation to event that doesn't belong to her. It says events belong to a user I think perhaps you meant that an event has many users, or did you mean an event could belong to many users? In any event I think your problem lies in your model definitions. I don't think the migrations are important, makes for a cluttered read.

Caveat: I shouldn't even be reading this right now, so this is not a comprehensive response by any means.

Upvotes: 0

sugaryourcoffee
sugaryourcoffee

Reputation: 879

Try

class Event < ActiveRecord::Base
  belongs_to :user
  has_many :invitations, through: :user
end

Upvotes: 2

Related Questions