'Rails has_many through has_and_belongs_to_many
I am trying to find way to get data from a has_and_belongs_to_many association through a secondary model. I'll say sorry now as I might not explain this right, so best I just show the associations and what I need to do. I am using Rails 5.
I have:
Incident Model:
incident has_and_belongs_to_many :apps
Apps Model:
app has_and_belongs_to_many :incidents
app belongs_to :service
Service Model:
has_many :apps
What I want to find is for my given service what Incidents its been involved in through the apps that it has, but I only want the unique Incidents.
Is there some way i can do @service.apps_incidents.unique
and get a list of the unique incidents.
My migrations look like this:
Service Table:
class CreateServices < ActiveRecord::Migration[5.1]
def change
create_table :services do |t|
t.string :name
t.timestamps
end
end
end
Apps Table:
class CreateApps < ActiveRecord::Migration[5.1]
def change
create_table :apps do |t|
t.string :name
t.references :service, foreign_key: true
t.timestamps
end
end
end
Incidents Table:
class CreateIncidents < ActiveRecord::Migration[5.1]
def change
create_table :incidents do |t|
t.string :name
t.timestamps
end
end
end
App/Incidents Join Table:
class CreateJoinTableAppsIncidents < ActiveRecord::Migration[5.1]
def change
create_join_table :apps, :incidents do |t|
t.index [:incident_id, :app_id]
end
end
end
Solution 1:[1]
You can use uniq_by
class Service
has_many :apps
has_many :incidents, through: :apps
end
You can then do
@my_service.incidents.uniq_by(&:incident_id)
Solution 2:[2]
Add incidents
to your Service
class Service
has_many :apps
has_many :incidents, through: :apps
end
Then
@service.incidents.uniq
OR
@service.incidents.distinct
This should do.
Solution 3:[3]
class Service
has_many :apps
has_many :incidents, -> { distinct }, through: :apps
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | SteveTurczyn |
Solution 2 | Sandip Mane |
Solution 3 | Sun Soul |