2017-08-24 3 views
8

Ich habe folgende ModelleActiveverbände Speicher, die zueinander zeigen, auf einmal

class Cargo < ApplicationRecord 
    has_many :destinations 
    has_many :assignments 
    accepts_nested_attributes_for :destinations 
    accepts_nested_attributes_for :assignments 
end 

class Destination < ApplicationRecord 
    has_one :assignment_coming_to_me, class_name: 'Assignment', foreign_key: 'arrive_destination_id' 
    has_one :assignment_leaving_me, class_name: 'Assignment', foreign_key: 'start_destination_id' 
end 

class Assignment < ApplicationRecord 
    belongs_to :start_from, class_name: 'Destination', foreign_key: 'start_destination_id' 
    belongs_to :arrive_at, class_name: 'Destination', foreign_key: 'arrive_destination_id' 
end 

ein visuelles Bild Geben, es ist so etwas wie diese

   +-------------+ 
      +---| Destination | 
      | +-------------+---+ <= start_from 
      |      | +------------+ 
      |      +---| Assignment | 
      |      | +------------+ 
+-------+ | +-------------+---+ <= arrive_at 
| Cargo | --+---| Destination | 
+-------+ | +-------------+---+ <= start_from 
      |      | +------------+ 
      |      +---| Assignment | 
      |      | +------------+ 
      | +-------------+---+ <= arrive_at 
      +---| Destination | 
      | +-------------+---+ 
      |      | 
      .      . 
      .      . 

Nun ist es eine Möglichkeit, Erstellen Sie die gesamten Datensätze auf einmal, angesichts der Parameter wie folgt? (Angenommen, die Ziele und Aufgaben sind miteinander verbunden sind ebenso wie die Reihenfolge der Parameter-Array)

{ 
    cargo: [ 
    destinations_attributes: [{place_id: ..}, {place_id: ...}, ...], 
    assignments_attributes: [{assignee_id: ..}, {assignee_id: ...}, ...], 
    ] 
} 

weiß ich Ziele zuerst, dann Speichern durch sie Iterieren Zuordnung der destination_ID einstellen kann die Arbeit erledigen, aber frage mich, ob es eine ist klügerer Weg.

+0

erstellen Wenn ich Ihr Schema verstanden, wollen Sie etwas durch Ziel zu verfolgen. Ich denke, es gibt eine bessere Möglichkeit, Ihre Modellassoziationen anzuordnen. Könnte bitte Ihr Datenbankschema an diese drei Tabellen senden. –

+0

@Pedro Assignmet hat start_destination_id und goal_destination_id, Destination hat cargo_id, das ist so ziemlich das Wesentliche – Ryo

Antwort

1

Nun, nicht die Details Ihres Problems zu wissen, werde ich beantworten, was ich denke, es wäre ein "smater" Weg zu lösen.

eine has_many durch Assoziation verwenden, wo Sie haben würde:

Fracht viele Ziele durch Zuordnungen hat.

Ziele hat viele Fracht durch Zuweisungen.

Zuordnungen enthält sowohl den Fremdschlüssel "Cargo" als auch "Ziele".

Wenn Sie Informationen über die Reihenfolge der Ziele benötigen, können Sie die Datensätze einfach anhand des create-Zeitstempels der Zuweisung abfragen.

Hier ist ein example-of-has-many-through-using-nested-attributes. Ich glaube, auf diese Weise können Sie Schienen haben, die alle Aufzeichnungen "automatisch" speichern. Außerdem können Sie die vom Verband angebotenen Abfragen verwenden, um alle drei Datensätze der Tabelle zu behandeln!

Lassen Sie mich wissen, was Sie denken! Viel Glück!

Link zu guide rails has_many_through assoaciton

+0

Danke für die Antwort, aber soweit ich weiß funktioniert es nicht für meinen Fall. Geschachtelte Attribute versuchen, neue Datensätze zu erstellen, es sei denn, die ID ist in params angegeben. Daher erstellt sie insgesamt 4 separate neue Zuweisungen für die 2 benachbarten Ziele und nicht 3 Zuweisungen, in denen eine davon geteilt wird, wie in der Abbildung dargestellt. – Ryo

+0

Sie haben Recht mit den verschachtelten Attributen. Wenn Sie alle zusammen speichern möchten, funktioniert diese Verknüpfung nicht. Es tut uns leid! –

1

Hierarchische Struktur ist zu reich für architektonische Zwecke: ich damit all Ihren Workflow reproduzieren könnte:

Am Ende des Codes I Kommentare

Sie

links laufen kann der Code im Terminal kopieren Sie es einfach auf test.rb Datei und führen ruby test.rb in Terminal

Und kurz vor, db in postgresql (oder mysql)

require "active_record" 

class Cargo < ActiveRecord::Base 
    establish_connection adapter: 'postgresql', database: 'test_destination' 

    connection.create_table table_name, force: true do |t| 
    t.string :name 
    end 

    has_many :delivery_places 

    accepts_nested_attributes_for :delivery_places 
end 

class DeliveryPlace < ActiveRecord::Base 
    establish_connection adapter: 'postgresql', database: 'test_destination' 

    connection.create_table table_name, force: true do |t| 
    t.string  :name 
    t.integer :order, default: 0 
    t.datetime :arrived_at 
    t.belongs_to :cargo 
    end 

    belongs_to :cargo 
    has_one :assigment 

    accepts_nested_attributes_for :assigment 
end 

class Assignee < ActiveRecord::Base 
    establish_connection adapter: 'postgresql', database: 'test_destination' 

    connection.create_table table_name, force: true do |t| 
    t.string :name 
    end 

    has_many :assigments 
    has_many :delivery_places, through: :assigments 
    has_many :cargos, through: :delivery_places 
end 

class Assigment < ActiveRecord::Base 
    establish_connection adapter: 'postgresql', database: 'test_destination' 

    connection.create_table table_name, force: true do |t| 
    t.belongs_to :delivery_place 
    t.belongs_to :assignee 
    end 

    belongs_to :delivery_place 
    belongs_to :assignee 
    accepts_nested_attributes_for :assignee 
end 

nikolay = Assignee.create! name: 'Nikolay' 
dec12 = DateTime.new(2017, 12, 12) 
dec13 = DateTime.new(2017, 12, 13) 
dec14 = DateTime.new(2017, 12, 14) 

Cargo.create! \ 
    name: 'candies', 
    delivery_places_attributes: [ 
    { 
     name: 'Moscow', 
     order: 0, 
     arrived_at: dec12, 
     assigment_attributes: { 
     assignee_id: nikolay.id 
     } 
    }, 
    { 
     name: 'Tokio', 
     order: 1, 
     arrived_at: dec13, 
     assigment_attributes: { 
     assignee_attributes: { 
      name: 'Ryo' 
     } 
     } 
    }, 
    { 
     name: 'Ny York', 
     order: 2, 
     arrived_at: dec14, 
     assigment_attributes: { 
     assignee_attributes: { 
      name: 'John' 
     } 
     } 
    } 
    ] 


# Let's find all my cargos 
puts nikolay.cargos 
# => [#<Cargo:0x007fae3e4475e8 id: 1, name: "candies">] 

# Do I have any cargos since 13 december till 14 december? 
puts nikolay.cargos.joins(:delivery_places).where(delivery_places: { arrived_at: dec13...dec14 }).distinct 
# [] 

# Do I have any cargos since 12 december till 14 december? 
puts nikolay.cargos.joins(:delivery_places).where(delivery_places: { arrived_at: dec12...dec14 }).distinct 
# => [#<Cargo:0x007fefac16a460 id: 1, name: "candies">] 

# Do I have cargo which I sent? 
nikolay.cargos.joins(:delivery_places).where(delivery_places: { order: 0 }).distinct 
# => [#<Cargo:0x007fefac16a460 id: 1, name: "candies">] 
+0

danke für die Antwort, aber ist es nicht im Wesentlichen die gleiche Antwort wie @Pedros. – Ryo

Verwandte Themen