【问题标题】:Ecto/Elixir/Phoenix - Fetch records with no associated recordEcto/Elixir/Phoenix - 获取没有关联记录的记录
【发布时间】:2021-03-08 19:22:28
【问题描述】:

我有这些架构:

  schema "players" do
    field :email, :string
    
    has_many :profiles, MyApp.Profile
    has_many :worlds, through: [:profiles, :world]
  end
  schema "worlds" do
    field :name, :string
    
    has_many :profiles, MyApp.Profile
    has_many :players, through: [:profiles, :player]
  end
  schema "settings" do
    field :mode, :string
    
    belongs_to :player, MyApp.Player
    belongs_to :world, MyApp.World
  end

默认情况下,所有玩家都应该在他们创建的每个世界中都有一个设置。但是由于我们代码中的逻辑错误,一些玩家在某些世界中没有设置。

现在我正试图找到那些在某些世界中没有现有settings 记录的players,以便我可以使用播种机为他们创建默认设置。

我尝试过这样的解决方法:

query = from profile in Profile

query
|> Repo.all()
|> Enum.each(fn profile ->
  case get_settings(profile.player_id, profile.world_id) do
    nil ->
      create_settings(profile.player_id, profile.world_id)

    _ ->
      :ok
  end
end)

它有效,但我想避免使用 case 语句。它花费了大量的数据库工作。 有什么方法可以使用查询在某些worlds 中获取那些没有settings 记录的players

【问题讨论】:

  • 你有返回你需要的结果的sql查询吗?我想您可以对玩家和世界进行完全连接,并过滤掉具有匹配配置文件的那些记录。老实说,当数据库查找失败时,我只会让我的服务返回默认值,而不是将多个(数百?数千?)默认配置文件记录塞进您的配置文件表中。

标签: postgresql elixir phoenix-framework ecto


【解决方案1】:

或多或少地使用Ecto.Query.join/5Ecto.Query.subquery/2

subquery =
  from profile in Profile,
    join: player in Player,
    on: player.id == profile.player_id,
    join: world in World,
    on: world.id == profile.world_id

query =
  from setting in Settings,
    join: profile in subquery(subquery),
    on: setting.player_id == profile.player_id and
        setting.world_id == profile.world_id 

或者,更简单的是,您可以直接将设置加入player_idworld_id 上的个人资料。

后者表明您实际上存在设计缺陷。设置和配置文件基本上是相同的实体,代表两次。这就是为什么你有不一致的地方。使用设置中的任何字段丰富配置文件,并完全摆脱设置。

【讨论】:

  • 感谢您的回答。我明白了,有一个设计缺陷。我正在考虑重新设计设置表并将其与配置文件表相关联,而不是与世界和玩家相关联。我已经尝试了您的示例,并且获得了所有现有设置记录。我要获取的是在某些世界中没有现有设置记录的玩家。
  • this 问题和我的很相似。我正在尝试使用 Ecto 片段将答案转换为长生不老药,但仍然没有运气。也许我做错了。
  • 使用outer_join 之类的,没有架构我无法测试它,但上述方法是正确的。
猜你喜欢
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-18
  • 2022-01-13
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
相关资源
最近更新 更多