2010-12-27 5 views
0

Ich habe eine Reihe von OrtenWie behalte ich die Reihenfolge der Assoziationen in Rails3?

locations = ["california", "new york", "florida"] 

I ein Modell namens foobar haben, dass has_many :places. das Place Modell belongs_to :foobar und hat eine relevante Spalte - name:string.

Ich habe ein verschachteltes Formular, das es mir erlaubt, Standorte auszuwählen, die für die Foobar gelten. die Optionen anbieten zu können, habe ich die Orte, bauen auf der Grundlage meiner Standortliste in meinem Controller:

class FoobarController < ApplicationController 
    def edit 
    @foobar = Foobar.find(params[:id]) 
    APP_CONFIG['locations'].each do |location| 
     @foobar.places.find_by_name(location) || @foobar.places.build(:name => location) 
    end 
    end 
end 

Das funktioniert fast ohne ein Problem. Der Grund, warum ich die Editiermethode einschließe, ist, dass dies die problematische ist. Die Liste der Orte, die DOES enthält, wird angezeigt, aber die Foobar Orte, die bereits vorhanden waren, werden oben angezeigt.


Beispiel Zeit! :)

  1. ich eine neue Foobar. In meinem Formular scrolle ich nach unten und sehe die Optionen "Kalifornien", "New York" und "Florida". Ich überprüfe "Kalifornien" und "Florida" und erstellen Foobar.

  2. Als nächstes gehe ich Foobar bearbeiten. Wieder, ich scrollen Sie nach unten zu den Orten, und ich sehe , dass ich zwei Optionen überprüft. Das ist groß, außer dass die Bestellung in , die die Optionen erscheinen, ist "California", "Florida", "New York" - Orte überprüft sind auf der Oberseite.

Wie kann ich die Reihenfolge der Orte von meinem ursprünglichen Array beibehalten?

Danke!


Update: der Ansicht Code:

<%= f.fields_for :places do |place| %> 
    <div class="place"> 
     <%= place.hidden_field :name %> 
     <%= place.check_box :checked %> 
     <%= place.label :checked, place.object.name %> 
    </div> 
<% end %> 
+1

Der Code, den Sie eingefügt haben, steuert nicht direkt die Reihenfolge von irgendetwas. Bitte posten Sie Ihren Ansichtscode. – jdl

+0

hat den Code gepostet. Vielen Dank! –

Antwort

1

Sie können nicht ... Jedenfalls nicht so, wie Sie es tun. Denken Sie darüber nach, was Schienen tun. Es sortiert automatisch nach der ID (PK) -Spalte einer Tabelle. Da die Datensätze, die Sie erstellen, keine ID haben, werden sie am Ende platziert - jedes Mal. Sie konnten FINAGLE und benutzen CREATE und fudge ids, aber das ist chaotisch und könnte in ernste Probleme laufen.

Um Ordnung (pun) zu halten, werden Sie irgendeine Art von Array-Pointer-System benötigen:

class FoobarController < ApplicationController 
    def edit 
    @foobar = Foobar.find(params[:id]) 
    @places = Array.new 
    APP_CONFIG['locations'].each do |location| 
     @places << @foobar.places.build(:name => location) 
    end 
    end 
end 

Ihrer Ansicht Dann werden Sie über das Array-Schleife müssen und manuell Erstelle das Formular. Ich empfehle, die Quelle anzusehen und zu sehen, wie das verschachtelte Formular zuerst erscheint.

Hier ist, wie ich es annähme - Build jedes Mal (kein find_by_name).Dann in Ihrem Modell Sie wollen:

class Foo < ActiveRecord 
    has_many :places 

    accepts_nested_attributes_for :places, :reject_if => { |a| !APP_CONFIG['locations'].include?(a) || Place.find_by_name(a).nil? || !Place.find_by_name_and_foo_id(a, self.id).nil? } 
end 

Jetzt habe ich eigentlich nicht, dass Code genau für Ihren Fall getestet, also werde ich es brechen;

1.) abweisen, wenn das eingereichte Attribut nicht im globalen Array (eher ein Sicherheitsproblem)

2.) ablehnen, wenn der Name nicht ein gültiger Ort (wieder, Sicherheit)

3.) abweisen, wenn der Ort bereits für diese foo (Klasse existiert, die has_many: Plätze)

+0

unbequem, aber es funktioniert. Du hast gesagt "zumindest nicht so wie ich es mache". Tue ich überhaupt etwas falsch? Vielen Dank!! –

+0

Ich habe Ihren Code aktualisiert, damit er in meiner Antwort besser funktioniert – sethvargo

Verwandte Themen