2017-01-17 14 views
2

Ich kenne es nicht "The Rails Way", aber ich versuche, Fremdschlüssel hinzuzufügen, um referenzielle Integrität auf der db-Ebene durchzusetzen. Ich möchte eine neue Tabelle namens recipe_ingredients erstellen, die über Fremdschlüssel verfügt, die auf eine Tabelle mit dem Namen recipes und eine mit den Namen Zutaten verweisen. Hier ist meine Migration:Fremdschlüssel funktioniert nicht wie erwartet

class CreateRecipeIngredients < ActiveRecord::Migration 
    def change 
    create_table :recipe_ingredients do |t| 
     t.references :recipe, null: false 
     t.references :ingredient, null: false 

     t.timestamps null: false 
    end 
    add_foreign_key :recipe_ingredients, :recipes 
    add_foreign_key :recipe_ingredients, :ingredients 
    end 
end 

Die Migration erfolgreich ist und erzeugt die folgenden:

              Table "public.recipe_ingredients" 
    Column  |   Type    |       Modifiers       | Storage | Stats target | Description 
---------------+-----------------------------+-----------------------------------------------------------------+----------+--------------+------------- 
id   | integer      | not null default nextval('recipe_ingredients_id_seq'::regclass) | plain |    | 
recipe_id  | integer      |                 | plain |    | 
ingredient_id | integer      |                 | plain |    | 
measurement | character varying   | not null              | extended |    | 
created_at | timestamp without time zone | not null              | plain |    | 
updated_at | timestamp without time zone | not null              | plain |    | 
Indexes: 
    "recipe_ingredients_pkey" PRIMARY KEY, btree (id) 
Foreign-key constraints: 
    "fk_rails_176a228c1e" FOREIGN KEY (recipe_id) REFERENCES recipes(id) 
    "fk_rails_209d9afca6" FOREIGN KEY (ingredient_id) REFERENCES ingredients(id) 

Das Problem ist, dass wenn ich versuche, einen neuen recipe_ingredient mit einem ungültigen recipe_id zu erstellen und/oder ingredient_id es hält noch es ist gültig. Wie kann ich die Datenbank dazu bringen, referenzielle Integrität für diese Felder durchzusetzen? Ich benutze eine postgresql db.

+0

Diese FKs sollten referentielle Integrität erzwingen. Wer hält diese ungültigen Zeilen für gültig? Und warum sind die Spalten "recipe_id" und "ingredient_id" auch nicht "null"? –

+1

Was meinst du mit gültig? Wenn das Modell sagt, dass es gültig ist, weil es dort keine Validierungen gibt, heißt das nicht, dass Sie es in die Datenbank einfügen können. – Iceman

+0

Wow, ich fühle mich dumm. Ich habe '.valid?' Verwendet, was natürlich nur die Validierungen im Modell ausführt. Es funktioniert korrekt, wenn ich versuche, in der Datenbank zu speichern. Danke @Iceman :-) –

Antwort

1

Der Aufruf valid? führt nur die Validierungen im Modell aus. Erst wenn Sie versuchen, es in die db einzufügen, treten die referenziellen Integritätsprüfungen ein.

In Rails 5 erfordert die Verwendung von belongs_to in Ihrem Modell automatisch, dass das übergeordnete Element vorhanden ist.

class Child < ApplicationRecord 
    belongs_to :parent 
end 

Sie können mit

aus dieser entscheiden
belongs_to :parent, required: false 
0

würde ich nicht unbedingt sagen, dass dies nicht die „Rails Weg“. Ich denke gerne an FKs und Modelvalidierungen wie das Tragen eines Gürtels und Hosenträgern. Für jene Zeiten wollen Sie wirklich nicht, dass Ihre Hosen herunterfallen.

+1

Das ist eine große Analogie lol –

Verwandte Themen