Frage

ich eine Benutzereinheit, die einen aktuellen Standort Feld (Stadt und Land) hat. Um diese Informationen zu halten habe ich eine Entität namens Stelle, die has_many Benutzer.

Ich bin nicht ganz sicher, ob ich in dem User-Modell „has_one“ oder „belongs_to“ setzen sollte, aber für das, was ich las, wenn ich es wollte, den Fremdschlüssel der Lage haben, soll ich „belongs_to“ setzen. Ich möchte auch in der Lage sein, die Benutzer jetzigen Standort zu bearbeiten, wenn der Benutzer bearbeiten. so ich bin mit verschachtelten Attributen. Aber wenn ich den Benutzer bearbeiten ich am Ende das Hinzufügen eines neuen Ort jedes Mal, ohne jemals es dem Benutzer zuordnet, die bearbeitet wurde. Kannst du mir helfen?

Mein Code ist die folgende:

#User Model
class User < ActiveRecord::Base
  ## Relationships
  belongs_to :current_location, :class_name => 'Location'
  accepts_nested_attributes_for :current_location
end

#Location Model
class Location < ActiveRecord::Base
  #Relationship
  has_many :users
end

# part of the _form_edit.haml
- form_edit.fields_for :current_location do |location_form|
  = location_form.label :location, "Current Location"
  = location_form.text_field :location

#Application Helper
#nested attributes for user and location
def setup_user(user)
  returning(user) do |u|
    u.build_current_location if u.current_location.nil?
  end
end

#in the user controller (added after edit)
def update
    @user = @current_user
    if @user.update_attributes(params[:user])
      flash[:notice] = "Account updated!"
      redirect_to account_url
    else
      render :action => :edit
    end
  end
War es hilfreich?

Lösung

Das genaue Problem Sie konfrontiert, wie andere haben darauf hingewiesen, dass der Controller nicht den Standort-ID empfängt, wie es sollte. Sieht aus mir der Lage-ID wird durch die falschen Parameter übergeben. Leider ist ein Standort-ID nicht auf einen neuen Datensatz vorhanden ist, so dass dieses in der Form nicht möglich ist.

Ihr Problem ergibt sich aus der Verwendung accepts_nested_attributes_for auf einem belongs_to Beziehung. Das Verhalten ist nicht klar definiert. Dies scheint ein Fehler dokumentiert werden. So ist die accepts_nested_attributes_for sollte auf einer Eins hat oder viele Seiten eine Beziehung hat.

Hier sind einige mögliche Lösungen:

  1. Move The accepted_nested_attributes_for zum Ort Modell und bauen Sie Ihre Formen umgekehrt.

    -form_for @location do |location_form|
     ...
     =location_form.fields_for @user do |user_form|
       ....
    

    Leider ist dies nicht für eine logische Art und Weise zu ermöglichen, Informationen zu präsentieren. Und macht die Bearbeitung der richtigen Benutzer schwierig.

  2. Verwenden Sie verbinden ein Modell und machen eine hat ein:. Durch Beziehung

    Ich bin ehrlich gesagt nicht sicher, wie gut accept_nested_attributes_for Arbeiten mit ein: durch Beziehung, aber es wird auf jeden Fall Ihr Problem lösen mit Datensätzen verknüpfen

  3. .
  4. Ignorieren accepts_nested_attributes_for und die Zuordnung in Ihrem Controller auf die altmodische Art und Weise handhaben.

    halten eigentlich die accepts_nested_attributes_for. Es bietet einige praktische Bequemlichkeit Methoden, nur um es zu dem update_attributes / create-Anweisung nicht bekommen lassen.

    def update 
      @user = @current_user 
      completed = false
      location_params = params[:user].delete(:current_location_attributes)
    
      User.transaction do
        @location = Location.find_or_create_by_id(location_params)
        @user.update_attributes(params[:user]) 
        @user.current_location = @location
        @user.save!
        completed = true
      end
      if completed
        flash[:notice] = "Account updated!" redirect_to account_url 
      else 
        render :action => :edit 
      end
    end
    

Felder für wird ein ID-Feld in dem current_location_attributes Hash automatisch ausgefüllt, wenn es nicht einen neuen Standort zu schaffen. Allerdings find_or_create_by_id, erfordert ein: id Eintrag in der Hash für sie zu arbeiten. Es wird mit einer korrekt Auto erhöhte ID erstellen, wenn die ID nicht in der Datenbank ist. Wenn Sie einen neuen Standort erstellen müssen Sie es hinzufügen. Einfachste es in die Form mit =location_form.hidden_field :id, 0 unless current\_location.new\_record? hinzuzufügen.

Allerdings möchten Sie vielleicht auf doppelte Lage Schöpfung zu reduzieren, und die Location.find_or_create_by_id Linie zu Location.find_or_create_by_location ändern. Dies wird auch auf die Fehler von Fehlern bei Einzigartigkeit Validierungen abgeholzt.

Andere Tipps

Sie bieten nicht die ID des verschachtelten Attribut. So Schienen denkt, es ist ein neues Geschäft.

- form_edit.fields_for :current_location do |location_form|
    = location_form.label :location, "Current Location"
    = location_form.text_field :location
    = location_form.hidden_field :id unless location_form.new_record?

Nicht sicher, ob die vorherige Antwort wirklich korrekt ist. Was Sie brauchen, ist die ID des Benutzers für den Standort angeben, nicht die Lage selbst.

- form_edit.fields_for :current_location do |location_form|
  = location_form.label :location, "Current Location"
  = location_form.text_field :location
  = location_form.hidden_field :user_id

In der Standardeinstellung belongs_to :current_location, :class_name => 'Location' erwarten, dass die Users Tabelle ein current_location_id Feld hat. Sobald Sie diese haben sollten Sie in der Lage sein, etwas zu tun:

@user = @current_user
@user.update_attributes(params[:user])

@location = @user.current_location or @user.build_current_location
@location.update_attributes(params[:location]) 

@user.current_location.save!
@user.save!
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top