2017-03-18 1 views
1

ich erstellt eine Join-Tabelle wie folgt:Wie aktualisiere ich ein postgres boolesches Feld mit Active Record in Rails 5?

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 

Und hier ist mein Modell:

class ParticipationRequest < ApplicationRecord 
end 

ich erfolgreich eine Zeile in der Tabelle erstellt. Allerdings, wenn ich versuchen, den Booleschen Wert zu aktualisieren, wie so:

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

pr die Zeile zurückgibt und ich bekomme eine ROLLBACK auf das Update mit dieser Nachricht:

TypeError: nil is not a symbol nor a string 

ich erkannt, dass die Join-Tabelle ist unterscheidet sich von meinen anderen Tabellen darin, dass es nicht wie meine regulären Tabellen indiziert ist. Der Primärschlüssel scheint eine Kombination aus user_id und purchase_id zu sein. Ich habe kein Problem mit update_attributes auf einer meiner anderen Tabellen. Gibt es an dieser Join-Tabelle etwas anderes, das es mir nicht erlaubt, ein Attribut auf diese Weise zu aktualisieren?

Antwort

1

create_join_table erstellt Tabelle ohne Primärschlüssel. Und kann Datensatz ohne Primärschlüssel nicht aktualisieren. Sie können also kein Feld im Datensatz ändern, weder approved noch user_id oder purchase_id. (Rails glaubt, Sie sollten Datensätze von "Join-Tabellen" nicht manuell aktualisieren)

Wenn Sie Datensätze von Modellen wie diesem ändern müssen, können Sie den Edelstein Composite Primary Keys verwenden.

Add Juwel Gemfile:

gem 'composite_primary_keys' 

In der Tabelle einen eindeutigen Index (dies ist optional, aber es besser zu machen):

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

Und setzen primary_keys zu Ihrem Modell:

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

    belongs_to :purchase 
    belongs_to :user 
end 

Das ist alles, jetzt sollten Ihre "Join-Tabelle" Datensätze in der Lage sein zu aktualisieren te.

+1

Vielen Dank! Es funktioniert hervorragend! – arjis02