如何在Rails中创建一个新的关联,以便加载其他关联



所以我现在有这样的系统:

class Tag < ActiveRecord::Base
# attr :name
end
class Article < ActiveRecord::Base
has_many :tag_associations, dependent:  :destroy
has_many :tags, through: :tag_associations
end
class Company < ActiveRecord::Base
has_many :articles
end
class User < ActiveRecord::Base
belongs_to :company
end

我想这样做:

user.company.articles.includes(:tags).all

我将这样使用它(我已经有一个问题,关于这方面的热切加载):

company.articles.all.select do |article|
article.tags.any? do |tag|
tag.name == 'foo'
end
end

如何在articles_by_tag的公司对象上创建新的关联

class Company < ActiveRecord::Base
has_many :articles
has_many :articles_by_tag, scope -> { |tag| ... }
end

我怎么会使用它呢?

company.articles_by_tag(tag: 'foo').all

这是一本X&Y问题。急于加载所有东西,然后在Ruby中使用带有块的.select循环浏览,基本上就像在餐厅点每一个披萨,只为了找到一个上面有凤尾鱼的披萨,然后扔掉其他所有东西。

相反,您使用INNER JOIN来过滤行:

Acticle.joins(:tags)
.where(tags: { name: 'foo' })

这将只返回标记表中匹配的行。

如果你想把它写进一个范围,你可以这样做:

class Article < ApplicationRecord
scope :with_tag, ->(name){ joins(:tags).where(tags: { name: name }) }
end

作为奖励,您可以使用GROUPHAVING查找带有标签列表的文章:

class Acticle  < ApplicationRecord
def self.with_tags(*tags)
left_joins(:tags)
.group(:id)
.where(tags: { name: tag })
.having(Tag.arel_table[Arel.star].count.eq(tags.length))
end
end 

相关内容

  • 没有找到相关文章

最新更新