3

楷模:

class User < ActiveRecord::Base
end

class Game::Session < ActiveRecord::Base
  has_many :session_users, foreign_key: 'game_session_id'
  has_many :users, through: :session_users
end

class Game::SessionUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :session, foreign_key: 'game_session_id'
end

表:

create_table :users do |t|
  ...
end

create_table :game_sessions do |t|
  ...
end

create_table :game_session_users, :id => false do |t|
  t.references :user, null: false
  t.references :game_session, null: false
  t.string :state, null: false
end

我创建和查询 Game::SessionUser 模型没有问题,但是在尝试更新它们时出现 SQL 错误。例如:

Game::Session.first.session_users.first.update(state: 'winner')

结果是:

ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR:  zero-length delimited identifier at or near """"
LINE 1: ...sers" SET "state" = $1 WHERE "game_session_users"."" IS NULL
                                                             ^
: UPDATE "game_session_users" SET "state" = $1 WHERE "game_session_users"."" IS NULL
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:811:in `prepare'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:811:in `prepare_statement'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:772:in `exec_cache'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `block in exec_delete'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:425:in `block in log'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:420:in `log'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:158:in `exec_delete'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:102:in `update'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `update'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/persistence.rb:489:in `update_record'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/locking/optimistic.rb:70:in `update_record'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/attribute_methods/dirty.rb:74:in `update_record'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/callbacks.rb:307:in `block in update_record'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:373:in `_run__995479063__update__callbacks'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:80:in `run_callbacks'
... 16 levels...
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:281:in `rollback_active_record_state!'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:269:in `save'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/persistence.rb:230:in `block in update'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:326:in `block in with_transaction_returning_status'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `block in transaction'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:210:in `within_new_transaction'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `transaction'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:209:in `transaction'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:323:in `with_transaction_returning_status'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/activerecord-4.0.0/lib/active_record/persistence.rb:228:in `update'
    from (irb):1
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
    from C:/Ruby200/lib/ruby/gems/2.0.0/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

数据库是 PostgreSQL,谢谢。

4

1 回答 1

2

我通过使用这个复合键 gem 解决了这个问题: http: //compositekeys.rubyforge.org/并确保使用 version 6.0.0

您只需要在模型中指定复合主键:

class Game::SessionUser < ActiveRecord::Base
    belongs_to :user
    belongs_to :session, foreign_key: 'game_session_id'

    self.primary_keys = :user_id, :game_session_id
end
于 2013-09-20T03:25:05.890 回答