ActiveRecord has_one relationship alongside a has_many relationship
I'm struggling to model a particular relationship with ActiveRecord. I currently have the following setup and working
class Schedule < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord:Base
belongs_to :schedule
end
with a database structure that looks like this:
schedules
- integer:id
tasks
- integer:id
- integer:schedule_id
What I'd like to be able to do is set one of the tasks to be the active task for a schedule by adding an "activ开发者_开发百科e_task_id" column to the Schedules table:
schedules
- integer:id
- integer:active_task_id
tasks
- integer:id
- integer:schedule_id
What I'm struggling with is how I should describe this within my ActiveRecord classes
should look like this
class Schedule < ActiveRecord::Base
has_many :tasks
belongs_to :active_task,
:class_name => 'Task',
:foreign_key => 'active_task_id'
end
class Task < ActiveRecord:Base
belongs_to :schedule
has_one :relevant_schedule,
:class_name => 'Schedule',
:foreign_key => 'active_task_id'
end
the conceptually tricky part is defining the 'relevant_schedule' relation. this isn't really needed in most cases (i.e. will not be used by code you write), is needed for compelteness of the ORM.
it's unlikely you'll ever want to use task.relevant_schedule
(in many cases it would be nil), you'll probably mostly want to use schedule.active_task
in your code.
'relevant_schedule' is just an arbitrary name, you may choose any other name you like. :class_name and :foreign_key must exactly match database and model names. perhaps the 'relevant_schedule' definition may be omitted altogether. i'm not sure.
It seems like you'd be better off using an attribute rather than creating a separate id. Maybe your task could have a boolean column called active
, then the active task for a schedule could be found with:
@schedule.tasks.select {|t|t.active?}
Or your could create named scope to accomplish the same thing.
精彩评论