【问题标题】:ActiveRecord::Base has_many fetch all for a given parentActiveRecord::Base has_many 获取所有给定父级
【发布时间】:2014-06-23 13:39:49
【问题描述】:

问题

下面我给出了我当前的 API 结果,但是,考虑到执行的 SQL,它不是我的预期或期望结果。谁能帮助我获得第二个 SQL 查询结果而不是第一个?

型号

console_game.rb

class ConsoleGame < ActiveRecord::Base
    self.table_name = 'console_game'
    self.primary_key = :id

    has_many :configurations, :class_name => 'Configuration'
end

configuration.rb

class Configuration < ActiveRecord::Base
    self.table_name = 'configuration'
    self.primary_key = :id
end

API

resource :configuration do
  desc "Finds all configurations associated with a game."
  params do
    requires :game, type: String, desc: "Game search.", documentation: { example: 'Battlefield 3' }
  end
  route_param :game do
    get do
      ConsoleGame.where(value: 'Battlefield 3').includes(:configurations)
    end
  end
end

调试控制台

D, [2014-05-06T15:11:59.071493 #31068] DEBUG -- : ConsoleGame Load (0.4ms) SELECT console_game.* FROM console_game WHERE console_game.value = 'Battlefield 3 ' D, [2014-05-06T15:11:59.073289 #31068] DEBUG -- : 配置负载 (0.3ms) SELECT configuration.* FROM configuration WHERE configuration.console_game_id IN (2) 127.0.0.1 - - [06/May/2014 15:12:08] “GET /configuration/game HTTP/1.1”200 34 25.9740

结果 - 获取 /configuration/game

[
    {
        id: 2,
        value: "Battlefield 3"
    }
]

期望的结果 - 获取 /configuration/game

[
    {
        id: 2,
        value: "x",
        device: 4,
        system: null,
        console_game_id: 2,
        creator: "yrdy",
        created_date: null,
        positive_votes: 0,
        negative_votes: 0
    },
    {
        id: 4,
        value: "ffds",
        system: 2,
        console_game_id: 2,
        creator: "gdfs",
        created_date: null,
        positive_votes: 0,
        negative_votes: 0
    }
]

注意:这个表上有很多外来索引,我想解决它们,但也许改天再解决。

ConsoleGame.where(value: 'Battlefield 3').includes(:configurations).as_json(include: :configurations)的结果

[
    {
        id: 2,
        value: "Battlefield 3",
        configurations: [
            {
                id: 2,
                value: "ffds",
                device: 4,
                system: null,
                console_game_id: 2,
                creator: "yrdy",
                created_date: null,
                positive_votes: 0,
                negative_votes: 0
            },
            {
                id: 4,
                value: "x",
                device: 4,
                system: 2,
                console_game_id: 2,
                creator: "gdfs",
                created_date: null,
                positive_votes: 0,
                negative_votes: 0
            }
        ]
    }
]

【问题讨论】:

  • @UriAgassi 我发布了我当前的结果和我想要的结果......我想得到我想要的结果,但我不明白它正在执行所有正确的 SQL 为什么它没有返回正确的结果。更新有问题,希望能更清楚地定义目标是什么
  • @UriAgassi 我得到了JSON,问题是我的.includes 是作为第二个SQL 查询运行的,但我的JSON 结果是第一个查询的结果而不是第二个查询.
  • 您正在查询ConsoleGame 并希望获得配置。您应该建立从ConfigurationConsoleGame 的另一个方向的关系并查询Configuration.joins(:console_game).where(console_game:{value:'Battlefield 3'}) 这将返回Configurations 而不是游戏。或者看看对你来说更好的范围。
  • 你试过简单吗:ConsoleGame.where(value: 'Battlefield 3').configurations

标签: ruby activerecord rack grape


【解决方案1】:

这行得通吗?

class ConsoleGame < ActiveRecord::Base
  #self.table_name = 'console_game'
  #self.primary_key = :id

  has_many :configurations #, :class_name => 'Configuration'
end

class Configuration < ActiveRecord::Base
  #self.table_name = 'configuration'
  #self.primary_key = :id
  belongs_to :console_game #, class_name: "ConsoleGame", primary_key: 'console_game_id', foreign_key: 'id'  #added relationship for ConsoleGame
end

resource :configuration do
  desc "Finds all configurations associated with a game."
    params do
      requires :game, type: String, desc: "Game search.", documentation: { example: 'Battlefield 3' }
    end
    route_param :game do
      get do
        #Search Configurations based on console game
        Configuration.joins(:console_game).where(console_game:{value: 'Battlefield 3'})
      end
    end
end

最好添加一个范围

class Configuration < ActiveRecord::Base
  #self.table_name = 'configuration'
  #self.primary_key = :id
  belongs_to :console_game #, class_name: "ConsoleGame", primary_key: 'console_game_id', foreign_key: 'id'  #added relationship for ConsoleGame
  scope :by_game,->(game){
           #verbosely
           #game_ids = ConsoleGame.where(value: game).pluck(:id)
           #where(console_game_id: game_ids)
           #one line
           joins(:console_game).where(console_game:{value: game})
           }
end    

用作

Configuration.by_game('Battlefield 3')

编辑

我已经注释掉了不需要的行,因为它们是设计所暗示的

【讨论】:

  • 我将其定义为belongs_to :console_game, :class_name =&gt; 'ConsoleGame',但这确实有效。 Scope 也很有效,谢谢,这真的帮助我更好地理解了这一点……我刚开始使用 ruby​​,我先做数据库,所以生成了这些类。
  • @abc123 没问题。另外提醒一下:id 总是被假定为primary_key 所以你不必说所以我已经注释掉了不需要向你展示的行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多