I've been reading and re-reading the Rails associations guide:
http://guides.rubyonrails.org/association_basics.html
This were close but not quite the same:
Ruby on rails active record associations
I'm not sure how to setup the following scenario.
Events has a status of either pending, open, or close.
I thought this would be simple enough to just have:
event has_one status
status belongs_to event
But this really isn't a one-to-one relationship since a status can belong to many events.
So then I thought I would do something like:
status has_many events
event belongs_to status
But this seems funny, because a status doesn't own an event. An event owns a status, right?
I had tried using enumerations and not have a status model. But that got tricky since it seems like ActiveRecord doesn't really support enumerations. I also figured that having a separate model might be good in case someone wants to expand on the number of options for status, like adding 'awaiting approval' or something.
This post suggests that my latter setup is okay, even though it reads funny:
Really easy Rails Active-Record Associations question
But I'm just wondering if I'm not aware of a better Ruby/Rails way of handling this simple scenario.
Thanks in advance!
Ignore that voice in your head: you're doing it fine. The real important of which model has belongs_to
is where the foreign key is stored. It's clear in this example that the foreign key should be stored in the Event
model, which means it should belongs_to :status
.
I also agree with the other posts, though - if you have got a small and fixed number of potential Status
records, consider creating an constant hash to store them instead of creating a whole database table for them.
Why not add a status
column to Event
(as an integer), and have something like this:
class Event < ActiveRecord::Base
STATUS_TYPES = {1 => "active", 2 => "inactive", 3 => "closed"}
def status
STATUS_TYPES[self[:status]]
end
def status=(new_status)
new_status = STATUS_TYPES.invert[new_status] if new_status.class == "String"
self[:status] = new_status
end
end