Topic: Compare two polymorphic models? Pretty sure I'm doing it wrong.

    if admin? 
      @downloads = Download.find(:all, :order => 'position')
    else
      @all_downloads = Download.find(:all, :order => 'position')
      @downloads = Array.new
      # for each, check that user has one of the roles associated with the download.
      @all_downloads.each do |d|
        current_user.roles.each do |r|
          if d.has_role?(r.name)
            @downloads << d
          end   
        end
      end  
    end
    @downloads.uniq! 

Anyone know a better way to do this?

High-Tech Creative Services http://new.techism.com/

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

You could try something like this:

   if admin? 
      @downloads = Download.find(:all, :order => 'position')
    else
      @all_downloads = Download.find(:all, :order => 'position').select{|d| (d.roles.map(&:name) & current_user.roles.map(&:name)).size > 0}
    end

I'm not sure if you need the if admin? or not if you do this, but doing and & between 2 arrays returns all the values that are in both arrays. So if you have an array of the role names for both the downloads and the current user and you & them together if any of them match you will get an array with at least one value.

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

Thanks for the response! 

That .select method is new to me...Is that a method of the activerecord class?

Let's try that...

Wow.  Works perfectly.  Thanks!

High-Tech Creative Services http://new.techism.com/

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

Final method:

 def index
    if admin? 
      @downloads = Download.find(:all, :order => 'position')
    else
      # get all downloads that share roles with current user.
      @downloads = Download.find(:all, :order => 'position').select{|d| (d.roles.map(&:name) & current_user.roles.map(&:name)).size > 0}
    end
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @downloads }
    end
  end
High-Tech Creative Services http://new.techism.com/

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

Well it's not quite part of the ActiveRecord class. Unfortunately it returns just an array of the object so you wouldn't be able to do a find or scoped method after doing a select, but it is very useful in this type of scenario.

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

I get it...ok...sorta...so it's really just tight one-line way of invoking a block after the find.  Then you are using array methods that I barely understand here...but that seem to kinda do a bitwise and type opperation on the arrays.

What's the size > 0 part?  A condition of some sort?

I love this syntax, but don't quite get it...

High-Tech Creative Services http://new.techism.com/

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

Ok, doing d.roles.map(&:name) just says go get all the roles for this download and return their names in an array. You can use the map method on any array of objects to return an array of whatever the attributes is.

This part:
(d.roles.map(&:name) & current_user.roles.map(&:name))
returns an array of all the roles names that match between the 2 arrays. So doing this:
(d.roles.map(&:name) & current_user.roles.map(&:name)).size
just gives you the number of roles that matched. From what I understand from your previous code, you only cared that a single role matched. So testing that the size returned was greater than 0 just means that at least 1 of the roles matched.

Then all that .select does is if that condition is true then keep that object, if it returns false then discard.

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

Cool!  Thanks for the break-down!

High-Tech Creative Services http://new.techism.com/

Re: Compare two polymorphic models? Pretty sure I'm doing it wrong.

Glad I could help. Hopefully it made a little more sense.