After reading some books and working on some tutorials, I’m working on my first Rails app. I’ve run into a question about some of my models.
In the app, I want to allow an admin user to create a pool of chores. At different intervals, the admin user can assign each chore to 0-N other users to be completed by them (e.g. Fred must do “Brush teeth” and “Make bed”, and Wilma also does “Brush teeth”). When the users complete their assigned chores, they receive points in recognition of their completing the chore. Those points have a default value in the pool but can be overwritten by the admin when assigning the chore to a particular user (e.g. Fred and Barney are both assigned “Set the dinner table”, Fred gets the default value for it when he does it, but Barney gets default + 10 when he does it).
Initially, I was putting everything that could be true of a chore on the Chore model (e.g. name, earnings, start, due, user_id, etc). I realized, however, some of those properties were not true of a Chore as it exists in the pool but were really true of the assignment of a chore. For example, start
and due
are not true of the chore as a Chore. start
and due
are true of a chore when it is assigned to a user. So I’m introducing a ChoreAssignment model that HAS_A Chore.
Here are some questions I’m running into:
First, am I thinking of this correctly that I need two models, one for the defaults that are part of the pool and one for an actual instance of doing the chore?
Second, if the ChoreAssignment HAS_A Chore (in the OO sense, not necessarily in the ActiveRecord sense) and the ChoreAssignment can override the default values of some of the Chore attributes when it is assigned, should the ChoreAssignment have the same attributes (db columns) as a Chore and it takes those from the Chore if it hasn’t been overwritten? Or is there some other way to model that?
Here are some example classes of what I’m thinking about in just Ruby not ActiveRecord:
class Chore
attr_reader :name, :earnings, :expires
def initialize(name:, earnings: 0, expires: false)
@name = name
@earnings = earnings
@expires = expires
end
end
# When this is saved to the db, it would get non-overwritable
# attributes from the chore (e.g. name).
class ChoreAssignment
attr_reader :chore, :user_id, :start, :due
def initialize(chore:, user_id:, start: nil, due: nil, earnings:, expires:)
@chore = chore
@user_id = user_id
@start = start
@due = due
@earnings = earnings || chore.earnings
@expires = expires || chore.expires
end
end
If I’m thinking of this correctly, how do I set up the ChoreAssignment in ActiveRecord?
Thanks for any help you can offer.