Search code examples
ruby-on-railsrubyruby-on-rails-4scopes

Scope on following association


I am trying to get back into using my scopes again, encountering some issues. I have the following 3 models

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable
  has_one :profile
  has_many :campaigns
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

class Campaign < ActiveRecord::Base
  belongs_to :user
end

I would like to be able to list all users who have created a campaign, though if they have created more than one I only want one instance of that user returned, I would also like to be able to access that users profile info..

I did come up with

scope :users_with_campaign, ->() {
  joins(:campaigns).where.not('campaigns.user_id' => nil) 
}

However that returns multiple instances of a user if i do this in my view for example

<% @user_campaigns.each do |u| %>
    <%= u.email %>
  <% end %> 

If anyone could advise how to get access to a users profile and get only one instance of that user returned that would be much appreciated, could i use the .uniq method maybe with this?

Thank You


Solution

  • scope :users_with_campaign, ->() {
      includes(:profile).joins(:campaigns).where.not('campaigns.user_id' => nil) 
    }
    

    Should work. Then you can do

    <% @user_campaigns.each do |u| %>
      <%= u.email %>
      <%= u.profile.field %>
    <% end %> 
    

    Or you could delegate the field you're trying to access

    class User < ActiveRecord::Base
      devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
      has_one :profile
      has_many :campaigns
      delegate :field, to: :profile
    end
    
    
    <% @user_campaigns.each do |u| %>
      <%= u.email %>
      <%= u.field %>
    <% end %> 
    

    Or you can prefix it with profile if that makes more sense

    delegate :field, to: :profile, prefix: true
    
    <% @user_campaigns.each do |u| %>
      <%= u.email %>
      <%= u.profile_field %>
    <% end %>