Ruby / Rails检查数组中的对象是否存在于其他Array中的方法

时间:2011-05-22 05:58:55

标签: ruby-on-rails ruby

想想这些代码行:

@boss_locations = BossLocation.order('min_level asc').all
@discovered = current_user.discovered_locations.includes(:boss_location).all

第一个获得所有可用的老板位置。第二个,获取所有发现的用户位置(user_id,boss_location_id),还包括boss_location对象。

现在,在我看来,我想根据@discovered上是否存在老板位置,呈现每个老板位置和“已发现”或“未发现”等消息。

现在,我的问题是如何以简单的方式提供我的观点。我可以遍历两个阵列,但我很确定这不是更好的方法。也许有一种很好的方法可以根据用户发现的老板位置来映射所有老板位置。你会怎么做?

编辑 - 变量有:

@boss_locations:

 => [#<BossLocation id: 670261930, name: "Fire Swamp", location_index: 1, min_level: 5, needed_gold_to_open: 500, created_at: "2011-05-18 05:35:48", updated_at: "2011-05-18 05:35:48">, #<BossLocation id: 723149845, name: "Rabbit Remains", location_index: 3, min_level: 15, needed_gold_to_open: 3000, created_at: "2011-05-18 05:35:48", updated_at: "2011-05-18 05:35:48">, #<BossLocation id: 81327760, name: "Grateful Plains", location_index: 2, min_level: 10, needed_gold_to_open: 1200, created_at: "2011-05-18 05:35:48", updated_at: "2011-05-18 05:35:48">]

@discovered:

 => [#<DiscoveredLocation id: 736487645, user_id: 986759322, boss_location_id: 670261930, created_at: "2011-05-22 05:37:01", updated_at: "2011-05-22 05:37:01">, #<DiscoveredLocation id: 736487646, user_id: 986759322, boss_location_id: 723149845, created_at: "2011-05-22 05:37:06", updated_at: "2011-05-22 05:37:06">, #<DiscoveredLocation id: 736487647, user_id: 986759322, boss_location_id: 81327760, created_at: "2011-05-22 06:01:35", updated_at: "2011-05-22 06:01:35">] 

3 个答案:

答案 0 :(得分:3)

这是放入控制器或视图的很多逻辑;考虑在BossLocation模型上创建discovered?方法。这样,您可以遍历@boss_locations并在每个上调用discovered?

  <% @boss_locations.each do |bl| %>
    <div>
      <%= "#{bl.name}: #{bl.discovered?(current_user)}" %>
    </div>
  <% end %>

该方法可能如下所示:

class BossLocation < ActiveRecord::Base
  def discovered?(user)
    user.discovered_locations.map(&:boss_location).include?(self)
  end
end

我在上面评论过你似乎喜欢这个想法,所以我把它写出来了。

答案 1 :(得分:1)

为了更好地封装您的数据模型,您需要修改模型类。

class BossLocation < ActiveRecord::Base
  has_many :discovered_locations
  has_many :users, :through => :discovered_locations

  def discovered_by?(user)
    self.users.include?(user)
  end
end

然后您在控制器中需要的只是:

@boss_locations = BossLocation.order('min_level asc').all

在你看来:

<% @boss_locations.each do |boss_location| %>
  <div>
    <%= boss_location.name %>:
    <%= boss_location.discovered_by?(current_user) ? 'Discovered' : 'Not Discovered' %>
  </div>
<% end %>

答案 2 :(得分:0)

由于两个数组中的对象不相同,您可能需要以自定义方式进行迭代:

<% @boss_locations.each do |boss_location|
  <div>
    <%= boss_location.name %>:
    <%= @discovered_boss_locations.inject('Not Discovered') { |result, element| result = 'Discovered' if element.boss_location_id ==  boss_location.id}
  </div>
<% end %>