gpt4 book ai didi

ruby-on-rails - 事件记录 : How to include another model based on Enum?

转载 作者:行者123 更新时间:2023-12-04 14:17:42 27 4
gpt4 key购买 nike

有一个带有枚举的 Post 模型

// Post.rb

enum category: {
job: 'job',
conference: 'conference'
}

一个组织拥有并属于许多帖子(通过连接表)

Org.includes(:posts).where(category: Post.categories[:job])

它似乎在尝试调用 Org 上的类别。有没有办法只写这个返回包含帖子的 Org,其中帖子有字符串“job”的枚举?

最佳答案

tl;dr 使用

Org.includes(:posts).where(posts: {category: :job})

较长的答案...

我想值得注意的是,您的问题实际上与enums 没有任何关系。它也与“包括另一个模型”无关。你真正想做的是 Specify Conditions on the Joined Tables您可以在 Active Record Query Interface guide 中阅读更多相关信息.

问题是您的 ActiveRecord 查询格式不正确:

Org.includes(:posts).where(category: Post.categories[:job])

您当前拥有的基本形式是:

Model.where(attribute: 'value')

:

.includes(:joined_models)

...位不会改 rebase 本形式。因此,ActiveRecord 将返回所有 Model 记录,其中 attribute 具有 value。或者,在您的情况下,所有 Org 模型,其中 categoryjob

但是,这不是您想要的。您需要所有具有 PostsOrgs,其中 Post categoryjob。 (或者,我想,“所有有职位的组织。”)

这就是 .includes(:joined_models) 位的用武之地:它允许您在 joined_models 上指定条件,其基本形式如下所示:

Model.includes(:joined_models).where(joined_models: {attribute: 'value'})
^^^^^^^^^^^^^

或者,在您的情况下:

Org.includes(:posts).where(posts: {category: Post.categories[:job]})

或者,正如 mu 在评论中所说:

Org.includes(:posts).where(posts: {category: :job})

现在,我不知道你在什么上下文中,但无论你在哪里,上面的代码都要求你的上下文了解很多关于 Org 以及它与 Post 的关系Post 的属性通常不是很好。所以,我建议你向 Org 添加一个方法,它允许你在你的上下文中解耦 Org 的知识:

class Org < ApplicationRecord 

class << self

def with_job_posts
includes(:posts).where(posts: {category: :job}})
end

end

end

现在你可以简单地做:

Org.with_job_posts

...并返回“所有有职位的组织”。而且您的上下文需要了解的关于 Post 及其属性的信息要少得多。

Post 还有一个类别 conference。所以,你可以这样做:

class Org < ApplicationRecord 

class << self

def with_job_posts
includes(:posts).where(posts: {category: :job}})
end

def with_conference_posts
includes(:posts).where(posts: {category: :conference}})
end

end

end

但是,如果您的 Post categories 开始增长,那将变得乏味。所以,改为:

class Org < ApplicationRecord 

Post.categories.each do |post_category|
define_singleton_method("#{post_category}"_posts) do
includes(:posts).where(posts: {category: post_category.to_sym})
end
end

end

现在您将拥有任意数量的方法,例如:

Org.with_job_posts
Org.with_conference_posts
Org.with_some_other_type_of_posts

super 棒!查看this Q&A更多信息来自 Jörg W Mittag .

顺便说一句,这看起来像是一种使用 enum 的潜在不寻常的方式。在docs ,它说:

Finally, it's also possible to explicitly map the relation between attribute and database integer with a hash:

class Conversation < ActiveRecord::Base
enum status: { active: 0, archived: 1 }
end

我一直认为映射枚举意味着使用整数作为值,而不是字符串。有趣。

关于ruby-on-rails - 事件记录 : How to include another model based on Enum?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58616540/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com