arjis02
arjis02

Reputation: 75

How do I update a postgres boolean field using Active Record in Rails 5?

I created a join table like so:

class CreateJoinTablePurchaseUser < ActiveRecord::Migration[5.0]
  def change
    create_join_table :purchases, :users, table_name: :participation_requests do |t|
    # t.index [:purchase_id, :user_id]
    # t.index [:user_id, :purchase_id]
    t.boolean :approved, default: false
  end
end

And here is my model:

class ParticipationRequest < ApplicationRecord
end

I created a row in the table successfully. However, when I try to update the boolean value like so:

pr = ParticipationRequest.find_by(user_id: 1, purchase_id: 1)
pr.update_attributes(approved: true)

pr returns the row and I get a ROLLBACK on the update with this message:

TypeError: nil is not a symbol nor a string

I recognized that the join table is different from my other tables in that it is not indexed like my regular tables. The primary key seems to be a combination of the user_id and purchase_id. I have no problem using update_attributes on any of my other tables. Is there something different about this join table that will not allow me to update an attribute this way?

Upvotes: 1

Views: 411

Answers (1)

Ilya Lavrov
Ilya Lavrov

Reputation: 2860

create_join_table creates table without primary key. And ActiveRecord can't update record without primary key. So you can't change any field in record, neither approved neither user_id or purchase_id. (Rails believes you should not manually update records of "join tables")

If you need to change records of models like this you may use gem Composite Primary Keys.

Add gem to Gemfile:

gem 'composite_primary_keys'

Add unique index to the table (this is optional but better to do):

class AddUniqueIdnexToParticipationRequests < ActiveRecord::Migration
  def change    
    add_index :participation_requests, [:purchase_id, :user_id], unique: true
  end
end

And set primary_keys to your model:

class ParticipationRequest < ActiveRecord::Base
  self.primary_keys = :purchase_id, :user_id

  belongs_to :purchase
  belongs_to :user
end

That's all, now your "join table" records should be able to update.

Upvotes: 1

Related Questions