在地图操作中,如何过滤掉特定记录?

时间:2014-12-24 03:00:50

标签: ruby-on-rails ruby

我有一条记录,当我返回一个关联关联时,它会向我发回一个集合,该集合还包含初始关联的记录。如何过滤掉原始记录?我知道这听起来很混乱,但下面的代码应该是不言自明的。

基本上我有一个记录d,当最终结果从此查询返回时 - d.parents.flat_map(&:children).uniq我不希望它包含d引用的记录。我如何以Ruby-esque的方式做到这一点?如果有一个Rails或Ruby内置方法可以做到这一点,那将是完美的,所以我可以优雅地将它链接到我现有的查询但我怀疑可能是这样的......我很有希望...所以额外的如果可以提供,请指出。

[91] pry(main)> d
=> #<User id: 2, email: "def@test.com", encrypted_password: "$2a$Bne..", reset_password_token: nil, reset_password_sent_at: nil, gender: 0>
[92] pry(main)> d.parents
=> [#<User id: 1, email: "abc@test.com", encrypted_password: "$2a$10$...", reset_password_token: nil, reset_password_sent_at: nil, gender: 0>,
 #<User id: 4, email: "jkl@test.com", encrypted_password: "$2a$...", reset_password_token: nil, reset_password_sent_at: nil, gender: 1>]
[94] pry(main)> d.parents.flat_map(&:children).uniq
=> [#<User id: 2, email: "def@test.com", encrypted_password: "$2a$10$...", reset_password_token: nil, reset_password_sent_at: nil, gender: 0>,
 #<User id: 3, email: "ghi@test.com", encrypted_password: "$2a$10$...", reset_password_token: nil, reset_password_sent_at: nil, gender: 1>,
 #<User id: 5, email: "mno@test.com", encrypted_password: "$2a$10$.mXgmN...", reset_password_token: nil, reset_password_sent_at: nil, gender: 1>]

修改1

这是我的协会的结构:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  attr_accessible :email, :password, :password_confirmation, :gender

  has_one :family_tree
  has_many :nodes
  has_many :relationships

  has_many :parent_child_relationships, class_name: "Relationship", foreign_key: :child_id
  has_many :parents, through: :parent_child_relationships, source: :parent

  has_many :child_parent_relationships, class_name: "Relationship", foreign_key: :parent_id      
  has_many :children, through: :child_parent_relationships, source: :child

  enum gender: [ :male, :female ]

  def has_children?
    !children.empty?
  end

  def has_parents?
    !parents.empty?
  end

end

这是我的Relationship.rb型号:

class Relationship < ActiveRecord::Base
  belongs_to :parent, class_name: "User"
  belongs_to :child, class_name: "User"

  attr_accessible :parent_id, :child_id
end

2 个答案:

答案 0 :(得分:1)

您可以使用Array#select()来过滤Ruby中的数组元素。

示例:

> a = [1,2,3]
> a.select{|x| not x.even?}.map{|x| x**2}
=> [1, 9]

在您的情况下,select子句将省略任何等于d

的记录

答案 1 :(得分:1)

d.parents.flat_map(&:children).uniq.reject{ |c| c == d }

d.parents.flat_map(&:children).uniq - [d]

但我认为您正在尝试获取用户的兄弟姐妹。如果您有模型设置,那么您应该执行以下操作:

class User < ActiveRecord::Base
  has_many :parents # with keys and class_name pointing to the same class
  has_many :children # with keys and class_name pointing to the same class

  has_many :parents_children, through: :parents, source: :children

  def siblings
    self.parents_children.where("users.id != ?", self.id)
  end
end

d.siblings # what you want

我无法找到将users.id != self.id条件传递给has_many关系的方法,否则has_many :siblings, options将是理想的。