我有3个模型User
,Post
和Favorite
。 user
可能有很多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
。即使不能在一次通话中完成,也可以通过更快的技术获知。
如果您需要更多信息,请与我们联系。
答案 0 :(得分:0)
似乎没有办法在一次通话中有条件地收集集合中的元素。以下是一些替代方案。
将compact
方法与map
一起使用。
def favorite_posts
favorites.includes(:favoriteable).where(favoriteable_type: 'Post')
.map { |f| f.favoriteable unless post.flagged }.compact
end
将select
与map
一起使用。
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值。