简体   繁体   中英

Rails Active Record Associations

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!

Doing this as an active record association is overkill. Think about it, create a whole table just to store 3 values in it that will never change?

What you really need is an enum. But of course, ruby doesn't have an enum.

Luckily, you can fake it.

module StatusCodes
  pending = 0
  open = 1
  closed = 2
end

Then you can do something like this

if @event.status == StatusCodes::open
  # do something
end

It's a much simpler solution and your code stays very readable.

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

您可能要考虑使用state_machine和一个简单的字符串列来实现状态,而不是使用关联或手动枚举。

You are wrong.

If you do

Event
 has_one :status

Status
 belongs_to :event

Rails will make sure it is a one-to-one association, so status will only belong to one event

I'm pretty sure this is what happens if you try to assign a event status to a different event

e1 = Event.first
status = e1.status

e2 = Event.new
e2.status = status
e2.save

Event.first.status #=> nil

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM