1

私がそれを実装した方法では、そうではないように見えます。

data_mapperの用語で-ドライバー、チーム、シーズンに参加する参加リソースエントリがあります

トラックとシーズンに参加する参加リソースレースがあります

エントリーとレースに参加する参加リソースの配置があります。

「特定のエントリーが参加したすべてのレースを次のようなもので見せてください」のようなことをしようとすると

@entry_a.races.all

このエラーが発生します

DataObjects :: SyntaxError:そのような列はありません:INNER(コード:1、SQL状態:、クエリ:SELECT"races"。"track_id"、"races"。"season _id"、"races"。"race_no" FROM "races" INNER JOIN "placings" ON INNER JOIN "entries"ON"placings"。"entry_team_id"="entries"。"team_id"AND"placings"。"entry_driver_id"="entries"。"driver_id"WHERE("placings"。 "entry_team_id" ='FER'AND"placeings"。"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 / expression1 ../ 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を作成することで、これを回避することができました。理想的ではありませんが、それは仕事をします。しかし、それはルビーの方法ではないようです。たぶん私のdbスキーマは最悪ですか?

これが私のモデルです(コードダンプについて申し訳ありません。完全なコードを引用していなかったために私を反対票を投じることを決めた仲間の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
4

1 に答える 1

1

いくつかのテストの後、表示されているエラーは複合キーを持つことに関連していると思います。レース用の単一のシリアル キーに変更してみてください。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)))
于 2013-03-19T20:38:53.890 に答える