有没有办法在单个方法调用中将map和delete_if应用于数组(Rails 3 activerecord)

时间:2014-05-17 23:41:08

标签: ruby ruby-on-rails-3 dictionary activerecord

我有3个模型UserPostFavoriteuser可能有很多favorite_posts。该关联是多态的,因为user也可以favorite一些其他类。目前,我已经定义了这种方法来检索用户最喜欢的帖子。

def favorite_posts
  favorites.includes(:favoriteable).where(favoriteable_type: 'Post').map(&:favoriteable)
end

我最近向名为Post的{​​{1}}添加了一个属性。如果此属性为flagged,我想将其从用户的收藏夹中删除。我致电true后,我可以添加delete_if方法。

map(&:favoriteable)

我想知道是否可以同时def favorite_posts favorites.includes(:favoriteable).where(favoriteable_type: 'Post').map(&:favoriteable).delete_if{|post| post.flagged == true} end 并删除帖子,如果它在一个方法调用中被标记?

我知道您可以为map(&:favoriteable)电话添加条件但是从我的实验中,该方法会返回一个长度相同的数组,但map值代替已标记的nil 。即使不能在一次通话中完成,也可以通过更快的技术获知。

如果您需要更多信息,请与我们联系。

2 个答案:

答案 0 :(得分:0)

似乎没有办法在一次通话中有条件地收集集合中的元素。以下是一些替代方案。

compact方法与map一起使用。

def favorite_posts
  favorites.includes(:favoriteable).where(favoriteable_type: 'Post')
           .map { |f| f.favoriteable unless post.flagged }.compact
end

selectmap一起使用。

def favorite_posts
  favorites.includes(:favoriteable).where(favoriteable_type: 'Post')
           .select { |f| !f.favoriteable.flagged }.map(&:favoriteable)
end

如果您没有手动构建结果的疑虑,请使用each_with_object

def favorite_posts
  favorites.includes(:favoriteable).where(favoriteable_type: 'Post')
           .each_with_object([]) { |f, posts| posts.push(f.favoriteable) unless post.flagged }
end

使用联接。

def favorite_posts
  Post.joins(:favoriteable).where(favoriteable: { user_id: id })
      .where(flagged: false)
end

有关类似的讨论,请参阅this

答案 1 :(得分:0)

您可以一起使用Array#select而不是map和delete_if。

def favorite_posts
    favorites.includes(:favoriteable).where(favoriteable_type: 'Post').select{|post| post.favoriteable && post.flagged == true}
end

或者你可以使用带有map的条件然后调用Array#compact来消除任何nil值。