using find for has many :through

I'm sorry I really can't figure out how to do this.. I have this reports that users should approve. But I don't know how to create a find which displays which report a current signed in user has not approved yet..

class User < ActiveRecord::Base   has_many :approvers   has_many :reports, :through => :approvers

class Report< ActiveRecord::Base   has_many :approvers   has_many :users, :through => :approvers

class Approver < ActiveRecord::Base   belongs_to :report   belongs_to :user

Though I am able to display which reports he has already approved using this query.. @user = User.find(session[:uid]) @report = @user.reports.find(:all, :include => :approvers)

How do I create a find to view all he hasn't approved yet?? =/

So right now, you don’t have any way of associating a report to a user with it being approved… the only way to give a user a report is to add it via the has_many :reports, :through => :approvers.

What you need to do is add a field to your approvers table in your database… it should be a boolean field named ‘approved’, and it should have a default value of false.

In a migration, that would look like this: add_column :approvers, :approved, :boolean, :default => 0

Then, you should define a function inside your User model called add_reports:

def add_reports(new_reports)

return false if not new_reports.is_a? Array new_reports.each {|report| self.reports << report unless self.reports.include? report} true end

def add_report(report) add_reports [report] end

And then also add an approve_report function:

def approve_reports(approved) return false if not approved.is_a? Array Approver.find(:all, :conditions => [‘report_id in (?) AND approved=false’, approved.collect {|report| report.id}]).each {|report| report.approved = true; report.save} end def approve_report(report) approve_reports [report] end

And finally, add two functions to give you the approved and unapproved reports

def approved_reports approved = self.approvers.collect {|a| a.report_id if a.approved == true} app_reports = self.reports.select {|r| true if approved.include? r.id} end def unapproved_reports

unapproved = self.approvers.collect {|a| a.report_id if a.approved == false} unapp_reports = self.reports.select {|r| true if approved.include? r.id} end

Now, you can do the following:

u = User.find(1) r = Report.find(1) reports = [r, Report.find(2)] u.add_report(r) u.add_reports(reports) u.unapproved_reports #at this point, this should be an array containing both the reports that we just added

u.approve_report(r) u.approved_reports #this should have 1 report, with report_id = 1 u.unapproved_reports #this should have 1 report, with report_id = 2