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®
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®
u.approved_reports #this should have 1 report, with report_id
= 1
u.unapproved_reports #this should have 1 report, with report_id =
2

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs