以下关联的范围

时间:2014-06-20 10:22:11

标签: ruby-on-rails ruby ruby-on-rails-4 scopes

我正在尝试重新使用我的示波器,遇到一些问题。我有以下3个型号

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

我希望能够列出已创建广告系列的所有用户,但如果他们创建了多个用户,我只想要返回该用户的一个实例,我还希望能够访问该用户个人资料信息..

我确实提出了

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

但是,如果我在我的视图中执行此操作(例如

),则会返回用户的多个实例
<% @user_campaigns.each do |u| %>
    <%= u.email %>
  <% end %> 

如果有人可以建议如何访问用户配置文件并且只返回该用户的一个实例,那将非常感激,我可以使用.uniq方法吗?

谢谢

2 个答案:

答案 0 :(得分:1)

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

应该有效。然后就可以了

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

或者您可以委派您尝试访问的字段

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 %> 

如果更有意义,你可以在配置文件前加上

delegate :field, to: :profile, prefix: true

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

答案 1 :(得分:1)

请注意,您不需要&#39; case,因为你使用的请求会被翻译成&#39; inner join&#39;这里

scope :users_with_campaign, -> {
  joins(:campaigns).uniq
}

scope :with_profile, -> { joins(:profile).uniq }

然后使用

User.users_with_campaign.with_profile.uniq

只会发出一个请求,您可以访问用户个人资料,例如

user.profile

这不会再提出一个请求,因为rails会从第一次请求中获得结果

P.S请注意,此请求仅包含具有个人资料的用户,如果您想要吸引所有用户,则应使用&#39; includes&#39;而不是&#39;加入&#39;