Forum: Ruby on Rails with_scope and a special relationship

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Carlos P. (Guest)
on 2007-07-12 19:22
(Received via mailing list)
Hi!

I have a little problem with two specially related models and an
accesor for one of them.

In our application, we have users (with a rights/roles subsystem) and
documents. For each document, we have some users related to it, each
one playing one role in that document. Some of them:

class Document < ActiveRecord::Base

belongs_to :adviser, :class_name => 'User', :foreign_key => 'adviser_id'
belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'

end

Documents are related to users this way, but users are related to
documents thinking that a user has a document if he participe in some
of the posible roles (adviser, owner...). But some special users have
access to more documents that those ones (for example, they can have
access to all documents created and associated on his office, that
it's another attribute of both the document and the user models). So,
instead of use has_many :documents on User model, we created the
following method on the User model:

class User < ActiveRecord::Base

def documents
    if self.can('view all documents')
      Document.find :all
    elsif self.can('view all office documents')
      Document.find :all, :conditions => { :office_id => self.office_id
}
    else # show only documents with direct user participation
      Document.find :all, :conditions => "(adviser_id = #{self.id} or
owner_id = #{self.id})"
    end
end

end

This works very well, but now we have a little problem. We want to use
the User::documents method by adding some additional conditions or
other find parameters, because we use customizable pagination, and a
selector to allow the users to filter the documents. Something like:

current_user.documents :conditions => 'status = 3', :limit => 20

We first tried to use with_scope:

def documents(options = {})
  with_scope :find => options do
    if self.can('view all documents')
      Document.find :all
    elsif self.can('view all office documents')
      Document.find :all, :conditions => { :office_id => self.office_id
}
    else # show only documents with direct user participation
      Document.find :all, :conditions => "(adviser_id = #{self.id} or
owner_id = #{self.id})"
    end
  end
end

But didn't work. Of course, we can create a method with all the
possibilities as parameters, and merge the conditions, but that is
boring (and doesn't look well).

Is there any other "Ruby-way" alternative?

Thanks!
Carlos P. (Guest)
on 2007-07-12 19:34
(Received via mailing list)
Ok, describing you the problem I found a solution:

class User < ActiveRecord::Base

  def documents(options = {})
    Documents.find_by_user(self, options)
   end

end


class Document < ActiveRecord::Base

  def self.find_by_user(user, options = {})
    with_scope :find => options do
      if user.can('view all documents')
        find :all
      elsif user.can('view all office documents')
        find :all, :conditions => { :office_id => user.office_id }
      else
        find :all, :conditions => "(adviser_id = #{user.id} or
owner_id = #{user.id})"
      end
    end
  end

end


It seems that with_scope :find only worked on the Document model. I
don't know exactly why, because my knowledge about with_scope is
minimum.

Anyway, I will grateful any suggestions.
Carlos P. (Guest)
on 2007-07-12 20:13
(Received via mailing list)
Ok, my last approach lets me use find parameters, but I can't use
other ActiveRecord methods like paginate:

current_user.documents.paginate ...

because documents returns an array, and paginate doesn't exist

If I use any other relationship defined with has_many, I can use
ActiveRecord methods, because what it returns is an ActiveRecord class
with predefined conditions (doesn't it?). For example, I can use:

current_user.roles.paginate ...


On 7/12/07, Carlos P. <removed_email_address@domain.invalid> wrote:
>
> owner_id = #{user.id})"
>
> Anyway, I will grateful any suggestions.
>


--
Carlos Alberto Paramio Danta               .--.
http://www.sinfoniadebits.com/            |o_o |
email & jabber: carlosparamio @ gmail.com |:_/ |
Web D. & Solutions - Learning   //   \ \
----------------------------------------( |    | )--
Fingerprint 41C6 D2BE 7DE7 AB61 C23F    /'\_   _/`\
            F697 5A1D 1849 01B8 D318    \___)=(___/
This topic is locked and can not be replied to.