Hi Guys, First off: Rails is amazing: Thanks! I’ve been trying unlearn
everything I know about web development and it is tricky - I’m not used
to things being beautiful
Anyway, I think I might be over complicating this but I’m working on a
project that tracks progress towards earning an award. Each award has
several groups of tasks and each group has one or more tasks. I have
defined the Award class below:
Class Award < ActiveRecord::Base
has_many :task_groups
has_many :tasks, :through => :task_groups
end
The completed tasks for each user is tracked in a table called
completed_tasks. And I want to show how many tasks the user has
completed for a particular award (and how many remain).
Here is what I tried:
Class Award < ActiveRecord::Base
has_many :task_groups
has_many :tasks, :through => :task_groups
has_many :completed_tasks, :through => :tasks
def completed_tasks_for_user(user)
completed_tasks.find_by_user_id(user.id)
end
end
Class Task < ActiveRecord::Base
has_many :completed_tasks
end
I was hoping that Active record would join awards to task_groups, then
to tasks, then to completed_tasks but the generated SQL was:
SELECT completed_tasks.* FROM completed_tasks INNER JOIN tasks ON
completed_tasks.task_id = tasks.id WHERE ((tasks.award_id = 3)) AND
(completed_tasks
.user_id
= 1) LIMIT 1
There is no award_id in the tasks table so the above statement doesn’t
work. It needs to go through the task_group table first.
I know I could iterate through the tasks and get the completed tasks for
a user that way but thought there might be a more ruby-licious way. Any
ideas?
Why not just have an extra field in the Task model called completed
(boolean). Next, create a method in the Task model that looks something
like this:
def tasks_completed_by_user(user)
find(:all, :conditions => {“user_id = ‘#{user}’”, “completed = ‘1’”)
end
That would give you a collection of Tasks that are marked completed.
Now I am a ROR newbie so the code above may need some tweaking… but
you get the idea.
Dan Hixon wrote:
Hi Guys, First off: Rails is amazing: Thanks! I’ve been trying unlearn
everything I know about web development and it is tricky - I’m not used
to things being beautiful
Anyway, I think I might be over complicating this but I’m working on a
project that tracks progress towards earning an award. Each award has
several groups of tasks and each group has one or more tasks. I have
defined the Award class below:
Class Award < ActiveRecord::Base
has_many :task_groups
has_many :tasks, :through => :task_groups
end
The completed tasks for each user is tracked in a table called
completed_tasks. And I want to show how many tasks the user has
completed for a particular award (and how many remain).
Here is what I tried:
Class Award < ActiveRecord::Base
has_many :task_groups
has_many :tasks, :through => :task_groups
has_many :completed_tasks, :through => :tasks
def completed_tasks_for_user(user)
completed_tasks.find_by_user_id(user.id)
end
end
Class Task < ActiveRecord::Base
has_many :completed_tasks
end
I was hoping that Active record would join awards to task_groups, then
to tasks, then to completed_tasks but the generated SQL was:
SELECT completed_tasks.* FROM completed_tasks INNER JOIN tasks ON
completed_tasks.task_id = tasks.id WHERE ((tasks.award_id = 3)) AND
(completed_tasks
.user_id
= 1) LIMIT 1
There is no award_id in the tasks table so the above statement doesn’t
work. It needs to go through the task_group table first.
I know I could iterate through the tasks and get the completed tasks for
a user that way but thought there might be a more ruby-licious way. Any
ideas?
On Jan 6, 9:30 pm, Melvin R. [email protected]
wrote:
Why not just have an extra field in the Task model called completed
(boolean). Next, create a method in the Task model that looks something
like this:
I’m with Melvin. Ideally, an object/entity shouldn’t change its class/
table just because its state has changed.
///ark
Thanks for the replies Mark and Melvin.
Since the tasks can indirectly belong to many users at once I couldn’t
simply add a completed boolean to that class. (“Run a mile under 6
minutes” might be completed by Jeremy but not yet by Alex).
I ended up adding this method to my user model:
def completed_tasks_in_current_award
tasks = []
completed_tasks.each do |ct|
if ct.task.task_group.award == award
tasks << ct.task
end
end
tasks
end
I’m guessing there might be a way to do it with more code - but this
will suffice for now.