Active Record has_one through

50 views
Skip to first unread message

Chris Berry

unread,
Oct 7, 2015, 8:47:54 PM10/7/15
to rubyonra...@googlegroups.com
I have two tables in my app which I am attempting to relate through a
join table. The Artist class which uses 'has_many through', works as
expected. However, the Event class using 'has_one through', brings back
nil.

class Artist < ActiveRecord::Base
has_many :artist_events, dependent: :destroy
has_many :events, through: :artist_events
end

class Event < ActiveRecord::Base
belongs_to :artist_event
has_one :artist, through: :artist_events
end

class ArtistEvent < ActiveRecord::Base
belongs_to :artist
belongs_to :event
end

In irb i get all events for an artist with "a.events" (where a =
Artist.first). But e.artist returns 'nil'. Whats strange is that
a.artist_event returns nill as well. However, when I run a 'find_by' on
the artist_event table and use e.id, the artist_event is returned.

I have tried changing the Event class to use has_one as opposed to
belongs_to, without effect.

What am I missing? Do I need to have an index in the schema?

--
Posted via http://www.ruby-forum.com/.

Colin Law

unread,
Oct 8, 2015, 4:19:41 AM10/8/15
to Ruby on Rails: Talk
On 8 October 2015 at 01:46, Chris Berry <li...@ruby-forum.com> wrote:
> I have two tables in my app which I am attempting to relate through a
> join table. The Artist class which uses 'has_many through', works as
> expected. However, the Event class using 'has_one through', brings back
> nil.
>
> class Artist < ActiveRecord::Base
> has_many :artist_events, dependent: :destroy
> has_many :events, through: :artist_events
> end
>
> class Event < ActiveRecord::Base
> belongs_to :artist_event
> has_one :artist, through: :artist_events

I have not done this but I think it should be
has_one :artist_event # to match ArtistEvent belongs_to event
has_one :artist through: artist_event # note, singular artist_event

However, in this scenario I don't think you need the join table at
all, why not just have
Artist has_many events
Event belongs_to artist

Colin

Matt Jones

unread,
Oct 8, 2015, 3:31:08 PM10/8/15
to Ruby on Rails: Talk


On Wednesday, 7 October 2015 20:47:54 UTC-4, Ruby-Forum.com User wrote:
I have two tables in my app which I am attempting to relate through a
join table.  The Artist class which uses 'has_many through', works as
expected.  However, the Event class using 'has_one through', brings back
nil.

class Artist < ActiveRecord::Base
  has_many :artist_events, dependent: :destroy
  has_many :events, through: :artist_events
end

class Event < ActiveRecord::Base
  belongs_to :artist_event 
  has_one :artist, through: :artist_events

Something hasn't been copied correctly here, because this shouldn't work - the `through` refers to an association (artist_events) that doesn't exist on Event.

As noted elsewhere, `belongs_to` is likely not the right association to use here; it's expecting an 'artist_event_id' column on the 'events' table.

You'll also want to carefully consider if `has_one` is the right association as well. The table structure you've set up (Artist / ArtistEvent / Event) is a classic many-to-many relationship. If an Event can truly only have one artist, this structure is not needed. If an Event can have many artists, than a has_one isn't correct.

--Matt Jones

Travis Eubanks

unread,
Oct 30, 2015, 10:38:45 AM10/30/15
to rubyonra...@googlegroups.com
why dont you just do this....


class Artist < ActiveRecord::Base
has_many :events, dependent: :destroy
end

class Event < ActiveRecord::Base
belongs_to :artist
end

a = Artist.first
a.events which will return a list of events connected to that artist

e = Event.first
e.artist which will return the artist that is connected to that event.

Maybe explain what your user story is to better understand. With what
you posted I comprehended the statement above.

Chris Berry

unread,
Nov 5, 2015, 11:32:20 AM11/5/15
to rubyonra...@googlegroups.com
Turns out the event table needed to have an artist_id column. I was
attempting to use the join table without a reference to the artist
table.

I dont know if that was the fix, because i also wrote a function in the
event model that used the artist_id to return artist data from the
database.

I did try your suggestion when initially building the classes...but
again, without the artist_id in the event table, it failed.

class Event < ActiveRecord::Base
has_many :city_events, dependent: :destroy

validates :EventID, uniqueness: true

def artist
Artist.find(artist_id)
end

def city
City.find(city_id)
end

end
Reply all
Reply to author
Forward
0 new messages