Rails: Setting a transient attribute on a set of objects from one model based on information from a junction model I have a user model, a task model, and a junction model user_task that saves the data joining the two:

class Task &lt; ActiveRecord::Base
  attr_accessor :completed_on
  has_many :user_tasks

class UserTask &lt; ActiveRecord::Base
  attr_accessible :task_id, :user_id, :completed_on
  belongs_to :user
  belongs_to :task

class User &lt; ActiveRecord::Base
  has_many :user_tasks, :dependent =&gt; :destroy
  has_many :tasks, :through =&gt; :user_tasks


In order to query the tasks and show if they're complete or not when a user is logged in, I have a transient attribute, (I think that's the correct terminology) an attr_accessor on the task model :completed_on. Right now I'm looping through the tasks as follows in order to get this attribute filled out. 

This just thrown in a controller as a quick hack to provide what I need.

  @tasks.each do |task| 
    if current_user.tasks.include? task
      task.completed_on = current_user.user_tasks.find_by_task_id(task.id).completed_on
    end
  end


I need something that, given an array of tasks and a user_id, loops through the tasks and fills that variable with the completed_on date if the user has finished that task. The goal for this is that when responding to JSON, I have overriden as_json on the task model to merge the completed_on attribute into the JSON hash:

h.merge({:completed_on =&gt; completed_on})


Possible ideas to get this done more properly:


Create a function on the tasks model that takes a user ID, joins the
user_tasks table to the tasks table, with a where clause to specify
the user. This idea is actually half baked and I'm not sure where to
go from here. 
Pretty much put the code above into the user model and    change
current_user to self. I'm not sure what to name it though,
completed_tasks doesn't fit since not all of them would be completed.
fill_completed_on may work.
Utilize a decorator somehow? Is it worth    it just for this single
attribute? If so, how would I structure it?
Something like Task.where(conditions) then Task.where(conditions).completed_by(user) then setting the completed_on on the latter and merging the two results.


It feels like I'm doing this the a bad way, and could be leveraging ActiveRelation/scopes somehow.

I also think there is a better way to do include completed_on in when needed and not have to override the task model's as_json to get it to appear.
The problem is that the data to render does not match the modelling. You call it "task", but if it includes a completed_on it's not a task, it's something more of a user_task. I definitely wouldn't use an accessor to accomplish this, that's messing with Task, this model should know nothing about completion dates of a particular user.

Even if you call it "tasks" in the frontend, conceptually in your app you should be rendering a collection of user_tasks. Something to start with (make sure, using includes or whatever, that user_task_by doesn't hit the DB repeatedly):

user_tasks = Task.where(...).includes(:users_tasks).map do |task|
  task.user_task_by(user) || task.user_tasks.new
end


Now you'd override UserTask#as_json to build a hash with the mixed structure (getting some attributes from task and completed_on from user_task).

Was this any help?