Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

update with has_many through SQL Error

Models:

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

Tables:

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

I have no problem creating and querying Game::SessionUser models, but I get SQL error when trying to update them. for example:

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

results in this:

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>'

The db is PostgreSQL, thanks.

like image 493
Adir Avatar asked Jul 12 '26 16:07

Adir


1 Answers

I fixed the issue by using this composite keys gem: http://compositekeys.rubyforge.org/ and make sure to use version 6.0.0.

You'll just need to specify the composite primary key in your model:

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
like image 73
Louis Avatar answered Jul 15 '26 08:07

Louis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!