Die Programmiersprache Ruby

Blog|

Forum|

Wiki  


Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]

Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
BeitragVerfasst: 24 Apr 2012, 21:18 
Offline
Schüler

Registriert: 13 Mai 2009, 11:18
Beiträge: 48
Hallo,

da ich in meiner Anwendung mehrere Objekte habe, die eine Adresse haben können, dachte ich mir, ich verwende dafür Polymorphis, müsste ja eigentlich gehen. So sieht es aktuell aus:


class Address < ActiveRecord::Base

belongs_to :addressable, :polymorphic => true

end

class User < ActiveRecord::Base

has_one :address, :as => :addressable
accepts_nested_attributes_for :address

end


Das müsste ja gehen dachte ich, zumindest habe ich beim Suchen auch schon einige Beispiele gefunden, die genau das machten und es somit auch funktionieren müsste, aber leider wird rein gar nichts gespeichert in der Tabelle!

Dann hab ich nochmal alles überprüft:

- accpets_nested_attributes_for ist vorhanden
- die Tabelle "addresses" hat sowohl eine Spalte "addressable_id" als auch "addressable_type"

Also eigentlich müsste es doch klappen, aber es wird einfach nicht in der Datenbank gespeichert. Weder wenn ich einen bestehenden Benutzer bearbeite, noch wenn ich einen neuen hinzufügen. Gebe ich allerdings manuell in der Datenbank etwas ein, wird das auf der Bearbeiten-Seite angezeigt. Gebe ich dann einen neuen Wert für ein Feld ein, wird das aber auch nicht gespeichert.

Seh ich den Fehler nur nicht oder klappt das so wie ich mir das gedacht habe einfach nicht?

Danke & viele Grüße
Martin

P.S.: Es ist rails 3.0.9


Zuletzt geändert von maddin am 25 Apr 2012, 11:35, insgesamt 1-mal geändert.

Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 09:26 
Offline
Meister

Registriert: 10 Dez 2009, 14:39
Beiträge: 212
accepts_nested_attributes_for ist nicht ganz ohne, was die Datenübernahme aus dem View angeht. Gib mal den View-Code für das UsersController#new Formular hier rein und den Code für UsersController#new|create.

_________________
Sorry, wenn ich doofe Fragen stelle, stehe noch ganz am Anfang :oops:


Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 10:15 
Offline
Schüler

Registriert: 13 Mai 2009, 11:18
Beiträge: 48
Hi,

also der Controller dazu sieht folgendermaßen aus:


def new
@user = User.new
@user.build_address
end

def create
@user = User.new(params[:user])
respond_to do |format|
if @user.save
format.html { redirect_to(users_path, :notice => "User successfully created.") }
else
format.html {
flash[:error] = "Fehler!"
render "new"
}
end
end
end

def edit
@user = User.find(params[:id])
end

def update
@user = User.find(params[:id])
respond_to do |format|
if @user.update_attributes(params[:user])
format.html { redirect_to(users_path, :notice => "User successfully changed.") }
else
format.html { redirect_to(edit_user_path(@user), :error => "Could not update user!") }
end
end
end


und die Views (new.html.haml):


.row
.span9
#content
%h1 Neuer Benutzer
= render :partial => "shared/messages"

%ul.errors
- @user.errors.each do |error|
%li= error


- form_for @user, :html => { :class => "form-horizontal" } do |f|
.control-group
%label{:for => "email", :class => "control-label"} E-Mail
.controls
= f.text_field :email, :class => "ui-textfield"
.control-group
%label{:for => "first_name", :class => "control-label"} Vorname
.controls
= f.text_field :first_name, :class => "ui-textfield"
.control-group
%label{:for => "last_name", :class => "control-label"} Nachname
.controls
= f.text_field :last_name, :class => "ui-textfield"
.control-group
%label{:for => "acronym", :class => "control-label"} Akronym
.controls
= f.text_field :acronym, :class => "ui-textfield"
.control-group
%label{:for => "password", :class => "control-label"} Passwort
.controls
= f.password_field :password, :class => "ui-passwordfield"
.control-group
= f.label :password_confirmation, 'Passwortbestätigung', :class => 'ui-passwordfield'
.controls
= f.password_field :password_confirmation, :class => "ui-passwordfield"

.control-group
= f.label :role, "Rolle", :class => "control-label"
.controls
= f.select("role", User::ROLES, {:include_blank => 'Bitte wählen'})

%h3 Adressdaten
= fields_for :address do |af|
= af.text_field :street
= af.text_field :street_addon
= af.text_field :zip
= af.text_field :country

.control-group
.controls
= f.submit "Benutzer anlegen", :class => "btn btn-success"

.span3
#left
= link_to 'Zurück zur Benutzerliste', users_path


edit.html.haml:


%h1= "Benutzer #{@user.email} ändern"


- form_for @user, :html => {:class => 'form-horizontal'} do |f|
.control-group
= f.label :email, :class => 'control-label'
= f.text_field :email, {:disabled => true}
.control-group
= f.label :first_name, :class => 'control-label'
= f.text_field :first_name
.control-group
= f.label :last_name, :class => 'control-label'
= f.text_field :last_name
.control-group
= f.label :acronym, :class => 'control-label'
= f.text_field :acronym
.control-group
= f.label :password, :class => 'control-label'
= f.password_field :password
= f.password_field :password_confirmation
.control-group
= f.label :role, :class => 'control-label'
= f.select("role", User::ROLES)


%h3 Adressdaten
= fields_for :address do |af|
= af.text_field :street
= af.text_field :street_addon
= af.text_field :zip
= af.text_field :country

%p= f.submit 'speichern', :class => 'btn btn-success'

.right
%p= link_to "Zurück zur Benutzerliste", users_path



Viele Grüße
Martin


Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 10:52 
Offline
Meister

Registriert: 10 Dez 2009, 14:39
Beiträge: 212
Ich liebe Twitter Bootstrap auch :D

Hmm, das sieht alles gut aus. Mit der Attribut-Whitelist arbeitest Du nicht?


attr_accessible :address_attributes

Kannst Du mal in dne UsersController#create ein

raise "#{params[:user].inspect}"

einfügen und mal schauen/posten, was genau ankommt ankommt?

_________________
Sorry, wenn ich doofe Fragen stelle, stehe noch ganz am Anfang :oops:


Zuletzt geändert von rubinson am 25 Apr 2012, 10:59, insgesamt 1-mal geändert.

Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 10:59 
Offline
Meister

Registriert: 10 Dez 2009, 14:39
Beiträge: 212
Ergänzung: Werden denn bei GET UsersController#new im Formular die Felder für die Adresse angezeigt?

Mir fällt gerade noch eine fiese Sache ein: Rails unterstützt kein my_object.others.build für Single Table Inheritance für die Assoziation. Das habe ich mir zurechtgepatcht, evtl. trifft das für polymorphe Assoziationen auch zu?!

Den Quellcode findest Du in diesem Namespace:

class ActiveRecord::Reflection::AssociationReflection
end

_________________
Sorry, wenn ich doofe Fragen stelle, stehe noch ganz am Anfang :oops:


Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 11:22 
Offline
Schüler

Registriert: 13 Mai 2009, 11:18
Beiträge: 48
Hi,

also die Felder werden in UsersController#new angezeigt. Ich hab auch attr_accessible drin und da steht sowohl :address als auch :address_attributes drin. Seltsamerweise funktioniert es aber auch mit has_many :addresses, :as => :addressable nicht.

Wenn ich mir mit raise ausgebe lasse, was übergeben wird, denke ich den Fehler gefunden zu haben. Das steht in params[:user]:

{"password_confirmation"=>"123456", "role"=>"Admin", "acronym"=>"sdfs",
"last_name"=>"sdf", "password"=>"123456", "first_name"=>"test", "email"=>"test@example.com"}

Eigentlich müsste doch hier als Attribut noch "address" mit sämtlichen Feldern auftauchen, tatsächlich steht das aber direkt in params[:address] drin.

Ich hab schon mehrfach gesucht und bin öfter darauf gestoßen, dass wohl Polymorphismus mit has_one nicht funktioniert, aber auch einige Beispiele gefunden, wo es ohne Probleme geht.

Ich hab dann mal alles an einem anderen Model getestet, weil mein User Model doch schon einige Abhängigkeiten hat. Aber selbst bei einem Model, wo als einzige Assoziation nur die Adresse steht funktioniert es nicht.

Echt zum Verzweifeln.


Viele Grüße
Martin

P.S.: Ja Twitter Bootstrap ist genial, kann man recht schnell schöne Ergebnisse erzielen!


Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 11:26 
Offline
Meister

Registriert: 10 Dez 2009, 14:39
Beiträge: 212
Hab' den Fehler bei Dir gefunden:

%h3 Adressdaten
= fields_for :address do |af| # fields_for muss natürlich vom User Formular ableiten
= af.text_field :street
= af.text_field :street_addon
= af.text_field :zip
= af.text_field :country

Mach mal

= f.fields_for :address do |af|

Dann sollte es funktionieren.

Warum hälst Du überhaupt 2 Views für das Formular vor (new und edit?)?

_________________
Sorry, wenn ich doofe Fragen stelle, stehe noch ganz am Anfang :oops:


Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 11:35 
Offline
Schüler

Registriert: 13 Mai 2009, 11:18
Beiträge: 48
Oh man, das mir das nicht aufgefallen ist... :roll: DANKE! Jetzt gehts natürlich ohne Probleme, neu Anlegen und Bearbeiten funktioniert!

Warum 2 Views? Weil sich die Formulare stark unterscheiden werden. Benutzer können angelegt werden, aber bearbeitet werden können Sie nur sehr eingeschränkt. Ich denke aber, dass die edit-View noch raus fliegt und das direkt in die show-View reinkommt.


Viele Grüße
Martin


Nach oben
 Profil  
 
BeitragVerfasst: 25 Apr 2012, 11:40 
Offline
Meister

Registriert: 10 Dez 2009, 14:39
Beiträge: 212
maddin hat geschrieben:
Oh man, das mir das nicht aufgefallen ist...


Naja, Du bist nicht der Einzige, der solche Sachen übersieht, das geht wohl allen so. Die Magic hat halt ihren Preis in Form von strikten Konventionen :)

_________________
Sorry, wenn ich doofe Fragen stelle, stehe noch ganz am Anfang :oops:


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach: