On Wednesday 31 May 2006 5:28 am, Daniel wrote: > I have three Models > > User, Group and File. > > User habtm group > Group habtm File > > How can I find all that files that a particular user has access to? > eg user.groups.files ? Step back from the problem a step. Forget that you are working with models or that you are dealing with habtm relationships in Rails. user.groups returns an array. And each of the elements in that array, if you call files() on it, returns another array. So all you are really looking at here is a requirement to iterate over an array of arrays, creating a set consisting of each of the unique values from those arrays. Strip all the Rails stuff away, and it's just a simple data problem. So, create a simple surrogate to think about: a = [[1,2,3], [2,3,4], [3,4,5], [4,5,6], [5,6,7], [6,7,8]] That's just an array of arrays. Arrays in Ruby provide some handy methods for treating them like sets. And what you want is the union of all of your sets. With an array, | performs a union operation. So: [1.,2,3] | [2,3,4] returns [1,2,3,4] So all that you need to do now is iterate through your array applying each sub array to a common array with the union operator. arr = [] a.each {|elem| arr = arr | elem} That works. You get: [1,2,3,4,5,6,7,8] FYI, Ruby also provides a method, inject(), that is perfect for this kind of operation. So, the above code can be rewritten like so: a.inject([]) {|arr,elem| arr | elem} inject() just takes a starting value and a block. The arguments to the block are an accumulator variable, which is initialized to the starting value passed to inject, and each successive element of the array inject it iterating over. The code in the block is evaluated and the result of the code is inserted into the accumulator variable. When all values of the array have been iterated over, inject() returns the final value of the accumulator. It's the loop for code that needs to accumulate values. Anyway, that's the way to solve the problem with an arbitrary set of arrays. So, now just apply it to your model. Something like this, probably: class User def files groups.inject([]) {|all_files, some_files| all_files | some_files} end end Hope this helps, Kirk Haines