Search code examples
ruby-on-railsuniquerails-activerecord

Uniq / Distinct Results in :through associations by configuring Rails


I have the following model setup

   class Tale < ActiveRecord::Base
   has_many :tale_culture_joins
   has_many :cultures, through: :tale_culture_joins, dependent: :destroy, crud: true, index: true
   has_many :tale_purpose_joins
   has_many :purposes, through: :tale_purpose_joins, dependent: :destroy, crud: true, index: true
   has_many :tale_book_joins
   has_many :books, through: :tale_book_joins, dependent: :destroy, crud: true, index: true
   has_many :tale_keyword_joins
   has_many :keywords, through: :tale_keyword_joins, dependent: :destroy, crud: true, index: true
   has_many :tale_character_joins
   has_many :characters, through: :tale_character_joins, dependent: :destroy, crud: true, index: true
   has_many :tale_moral_joins
   has_many :morals, through: :tale_moral_joins, dependent: :destroy, crud: true
   has_many :values, through: :morals, index: true
   has_many :tale_event_joins
   has_many :events, through: :tale_event_joins, dependent: :destroy, crud: true

   end

   Tale -> Moral -> Value
   Tale(1) -> Moral(1,2)
   Moral(1) -> Value(1,2)
   Moral(2) -> Value(2,3)
   Tale(1).values # => [1,2,2,3]

I understand the reasoning behind it, can I configure rails to not only return but also query/build up the return value with uniqs so that uniq condition is passed to sql query itself


Solution

  • If I understand correctly, you want to be able to, for example, do Table.events and get a collection of unique events. You can get this behavior for events like this:

    has_many :events, -> {uniq}, through: :tale_event_joins, dependent: :destroy, crud: true
    

    You can include a similar -> {uniq} scope on any relationship for which you want a unique collection.