I assume that post
is an ActiveRecord object and messages
is a has_many
relation on that class.
When calling post.messages
, you don't immediately get an array back. Instead, Rails first creates an ActiveRecord::Relation
object which contains the query you just built before it is executed. This allows you to chain finder methods (e.g. where
, select
, ...) and build a full query before it is sent to the database for execution.
Now, as you don't have an array, its methods can operate differently (and accept different arguments) than Array methods. The uniq
method in this case is an alias to distinct
which instructs the query to be created to be DISTINCT
. As you are not yet dealing with an actual array of objects, filtering with a block won't work here yet.
In order to solve this, you have two options:
You can force ActiveRecord to run the query and return an array using the to_a
method where you can then use the Array's uniq
method with a block as you attempted above:
post.messages.to_a.uniq { |x| x.user_id }
You can create an appropriate query to only return the data you actually need. This can be challenging in this case as the required SQL is probably rather complex and might not be supported by ActiveRecord's query generator (and would this be created by hand). See this question for details how you could create appropriate queries.