【问题标题】:can I join two join resources together?我可以同时加入两个加入资源吗?
【发布时间】:2013-03-15 08:36:12
【问题描述】:

按照我的实现方式,似乎不是。

在 data_mapper 术语中 - 我有一个加入资源条目,它加入了 Driver、Team 和 Season

我有一个加入赛道和赛季的资源竞赛

我有一个加入 Entry 和 Race 的加入资源放置。

当我尝试执行诸如“向我展示某个特定参赛者参加的所有比赛时,例如

@entry_a.races.all

我收到此错误

DataObjects::SyntaxError: no such column: INNER (code: 1, sql state: , query: SELECT "races"."track_id", "races"."season _id", "races"."race_no" FROM "races" INNER JOIN "配售" ON INNER JOIN "entries" ON "配售"."entry_team_id" = "ent ries"."team_id" AND "配售"."entry_driver_id" = "entries"."driver_id" WHERE ("配售"."entry_team_id" = 'FER' AND " 排名"."entry_driver_id" = 'MAS') GROUP BY "races"."track_id", "races"."season_id", "races"."race_no" ORDER BY "races "."track_id", "races"."season_id", uri: sqlite3:C/devProjects/formula1../spec/resources/test.db?scheme=sqlite3&user=&pas Sword=&host=C&port=&query=&fragment=&adapter=sqlite3&path=/devProjects/formula1../spec/resources/test.db)

很容易看出这里发生了什么,由 .all 方法包装的查询并不期望连接时的连接。

我设法通过编写一些自定义 sql 来解决这个问题。虽然不理想,但它确实可以完成这项工作。不过,这似乎不是红宝石方式。也许我的数据库架构很烂?

这是我的模型(对代码转储感到抱歉。我被一个 SO 因为我没有引用完整的代码而决定对我投反对票的同事烫伤)

require "rubygems"
require "sqlite3"
require "data_mapper"
require "bigdecimal"

#note that Dir.pwd refers to the location of the file that calls
if ENV["run_mode"] == "prod"
    DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/data/prod.db")
else
    DataMapper::setup(:default, "sqlite3://#{Dir.pwd}../spec/resources/test.db")
end

class Entry

    include DataMapper::Resource

    belongs_to :team,   :key => true
    belongs_to :driver, :key => true
    belongs_to :season, :key => true

    has n, :placings
    has n, :races, :through => :placings

    def find_races

        return repository.adapter.select('SELECT races.track_id, races.season_id, races.race_no FROM races INNER JOIN placings ON races.track_id = placings.race_track_id INNER JOIN entries ON placings.entry_driver_id = entries.driver_id WHERE (entries.team_id = ? AND entries.driver_id = ?)', self[:team_id], self[:driver_id])

    end

end

class Track

    include DataMapper::Resource

    property :id, String, :key => true

    has n, :races

end

class Race

    include DataMapper::Resource

    property :race_no, Integer

    belongs_to :track,  :key => true
    belongs_to :season, :key => true

    has n, :placings
    has n, :entries, :through => :placings


end

class Placing

    include DataMapper::Resource

    property :id, Serial #put this in because dm was complaining that foreign keys from entry object were not unique
    belongs_to :race    
    belongs_to :entry

end

class Season

    include DataMapper::Resource
    property :id, Integer, :key => true

    has n, :races
    has n, :entries

end

class Driver

    include DataMapper::Resource
    property :id, String, :key => true
    property :team, String
    property :ptd, Integer
    property :races, Integer
    property :grid, Object
    property :race, Object
    property :cumulativePoints, Object #the number of points accumulated at a particular point in the season
    property :hcScore, Integer
    property :domScore, Integer
    property :nation, String
    property :wins, Integer
    property :podiums, Integer

    has n, :entries
    has n, :teams, :through => :entries

end

class Team
    include DataMapper::Resource
    property :id, String, :key =>  true
    property :name, String
    property :ptd, Integer
    property :domScore, Integer
    property :nation, String

    has n, :entries
    has n, :drivers, :through => :entries

    def initialize(team_id)
        self[:id] = team_id
        self.save!
    end

    def add_driver(driver_id)
        @driver = Driver.create(:id => driver_id)
        Entry.create(:driver => (Driver.get driver_id), :team => self, :season =>  Season.last)
        return @driver
    end

end

class Nation
    include DataMapper::Resource
    property :id, String, :key => true
    property :ptd, Integer
    # could possibly have the drivers, teams and engines here as well
end

if ENV["run_mode"] == "test"
    DataMapper.finalize.auto_migrate!
else
    DataMapper.finalize.auto_upgrade!
end

【问题讨论】:

    标签: ruby ruby-datamapper sqlite3-ruby


    【解决方案1】:

    经过一些测试,我认为您看到的错误与组合键有关;尝试更改 Race 的单个 Serial 密钥。我认为这是 DM 中的一个错误。

    我在尝试使用复合键执行 Driver.first.races 时出现了相同的错误,但仅使用串行键就可以了:

    $KCODE='u'
    
    require 'rubygems'
    require 'dm-core'
    require 'dm-migrations'
    
    DataMapper::Logger.new($stdout, :debug)
    DataMapper.setup(:default, "sqlite::memory:")
    
    class Entry
      include DataMapper::Resource
      #property :id, Serial # maybe also here? Although everything seems to work without
      property :grid, Integer
      property :position, Integer
      belongs_to :driver, :key => true
      belongs_to :race, :key => true
    end
    
    class Driver
      include DataMapper::Resource
      property :name, String, :key => true
      has n, :entries
      has n, :races, :through => :entries
      def podiums; entries(:position => (1..3)) end
      def wins; entries(:position => 1) end
    end
    
    class Race
      include DataMapper::Resource
      property :id, Serial
      belongs_to :track
      belongs_to :season
      has n, :entries
      has n, :drivers, :through => :entries
    end
    
    class Season
      include DataMapper::Resource
      property :year, Integer, :key => true
      has n, :races
    end
    
    class Track
      include DataMapper::Resource
      property :name, String, :key => true
      has n, :races
    end
    
    DataMapper.finalize.auto_migrate!
    
    Entry.create(
      :driver => Driver.new(:name => "Kimi Räikkönen"),
      :grid   => 7, :position => 1,
      :race   => Race.new(
        :track  => Track.new(:name => "Albert Park"),
        :season => Season.new(:year => 2013)))
    

    【讨论】:

    • 感谢您查看并整理我的代码的其他部分!对于最新的例子:) Go IceMan :)
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多