noname
noname

Reputation: 565

Rails. Keeping list in database is it good idea? What relation I should use?

I struggling with one little thing and I am not sure how I should do it. I have User and Status table. And I am thinking I should add StatusList table which will keep all available statuses. User will keep user data, but Status will keep current user status. So it might look like:

Table User id, name, email
Table Status user_id, status_list_id
Table StatusList id, name

And I was thinking about association like:

User
  has_one :status
  has_one :status_list, through: :status

Status
  belongs_to :user
  has_one :status_list

StatusList
  belongs_to :status

But this is not working like I expect. I mean when I try do:

@u = User.last
@u.status # => "id: 1"
@u.status.status_list # => No such column "status_lists"

But when I checked ActiveRecord::Base.connection.tables I see ['users', 'statuses', 'status_lists']. So I start looking for solving that problem in google, but I can not find anything so I am here asking, How this relation should looks like? If my idea is good why is not working like I expect?

Thanks for any hints which helps me find solution.

Upvotes: 0

Views: 50

Answers (2)

coorasse
coorasse

Reputation: 5528

This is the correct solution in case you want to have a high degree of freedom in manipulating statuses, maybe an admin can change them at any time from an admin console or even the users can create new statuses themselves. In that case use the following:

User      
  has_one :status_list, dependent: :destroy
  has_one :status, through: :status_list

StatusList
  belongs_to :user
  belongs_to :status

Status
  has_many :status_lists, dependent: :destroy
  has_many :users, through: :status_lists

In case that is not your situation and you have just a restricted set of statuses that are not going to change very often (they still can) and that will imply anyway new developments to manage the new status, than you should keep it much simpler, remove statuses tables, and use enums from Rails (http://api.rubyonrails.org/v5.1.1/classes/ActiveRecord/Enum.html).

Change your users table to have a status string column and define, in the user model, the list of statuses:

enum status: [ active: 'active', archived; 'archived' ]

I strongly suggest you to define enums with strings, instead of integers, as values in the DB, because it's easier to maintain and change in the future.

Upvotes: 0

widjajayd
widjajayd

Reputation: 6253

here is you can setup

User
  # -> status_lists -> statuses
  has_many :status_lists, :dependent => :destroy
  accepts_nested_attributes_for :status_lists,   :allow_destroy => :true  
  has_many :statuses, through: :status_lists

StatusList
  belongs_to :user
  belongs_to :status

Status
  # -> status_lists -> users
  has_many :status_lists, :dependent => :destroy
  accepts_nested_attributes_for :status_lists,   :allow_destroy => :true  
  has_many :users, through: :status_lists

if you want to setup many to many relation ship with StatusList as the "connection model" , you can setup as my sample above

@user = User.last
@user.statuses # this will show all the user statuses
@status = Status.last
@status.users # this will show you all user that has same status

Upvotes: 0

Related Questions