rails group by association

时间:2015-08-02 07:47:48

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

我在控制器中有一些集合,如下所示:

def show
  @cave = Cave.includes(cubs: :mamabear).where(id: params[:id]).first
  @cubs = @cave.cubs
  @papabear = Papabear.first
  @dens = Den.where(papabear_id: @papabear.id)
end

现在我正试图通过窝点对幼仔进行排序,这样我就可以用

显示幼仔
@dens.each do |d| 
  d.cubs
end

所以我写了以下内容:

def show
....
  @dens.each do |den|
    den.cubs = []  ## < --- Den does not have an association with Cub ##
    @cubs.each do |cub|
      den.cubs << cub if cub.mamabear.den_id == den.id
    end
  end

  #reject dens if they don't have cubs
  @dens = @dens.reject { |den| den.cubs.all?(&:blank?) }

end

但是现在我得到一个未定义的方法'小熊为Den'错误,因为Den与Cub无关。如何在没有关联的情况下为每个Den分配一个Cub数组?

3 个答案:

答案 0 :(得分:1)

1:我会为小熊创建一个标准的小熊队协会。可能是标准has_many On dens,所以每只幼仔都有一个den_id。

你正在搞乱重新发明轮子,否则。

2:你可能会发现未定义的方法是'cubs ='而不是'cubs'。这是一个重要的区别,因为它说明了抛出错误时代码正在做什么。

3:如果你真的想忽略第1点并使自己从控制器中填充任意属性,你可以将其添加到Den模型中。

attr_accessor :cubs

答案 1 :(得分:1)

如果您想在多个位置获取属于cubs的{​​{1}},那么关联是处理此类方案的最佳方式。如果你不想实现关联。你可以尝试这个解决方案

den
显示页面上的

你可以这样做

@den_cubs = []
@dens.each do |den|
  cub_for_den= {}  #here we are initializing hash each time for new den
  @cubs.each do |cub|
    cub_for_den[cub.id] = cub if cub.mamabear.den_id == den.id
  end
  @den_cubs << cub_for_den #put the hash in array
end

@den_cubs = @den_cubs.reject { |dc| dc.blank? }

答案 2 :(得分:1)

你是否考虑过对幼崽使用“有很多通过”的关联 - &gt;窝点和窝点 - &gt;崽?

http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

示例:

class Den
  has_many :mamabears
  has_many :cubs, through: :mamabears
end

class Cup
  belongs_to :mamabear
  has_one :den, through: :mamabear
end

然后你应该可以做类似的事情:

den.cups #=> [<Cup ...>]
cup.den #=> <Den ...>