3 models in 1 template

hello,

I’d like to get user data in one template.

The relations are:
user has_one user_adress
user has_one user_account

The following template doesn’t save any (valid) data. I think the
submit button doesn’t work.
All 3 models should be validated when save is called.

<%= error_messages_for ‘user’ %>
<%= error_messages_for ‘user_adress’ %>
<%= error_messages_for ‘user_account’ %>

Please enter your data:
<% form_for :user do |form| %>
    <label for="user_first_name">firstname:</label>
    <%= form.text_field :first_name, :size => 40 %>
  </p>
  <p>
    <label for="user_surname">surname:</label>
    <%= form.text_field :surname, :size => 40 %>
  </p>
  <p>
    <label for="user_birthdate">date of birth</label><br/>
    <%= date_select 'user', 'birthdate', :include_blank => true,
    :order => [:day, :month, :year], :start_year => 1900, :default

=> :blank %>



email:
<%= form.text_field :email, :size => 40 %>



username:
<%= form.text_field :username, :size => 40 %>



password:
<%= form.password_field :password, :size => 40 %>



passwort
confirmation:
<%= form.password_field :password_confirmation, :size => 40 %>


<% end %>
<legend>Your adress:</legend>
<% form_for :user_adress do |form| %>
  <p>
    <label for="user_adress_street">street:</label>
    <%= form.text_field :street, :size => 40 %>
  </p>
  <p>
    <label for="user_adress_nr">number:</label>
    <%= form.text_field :nr, :size => 40 %>
  </p>
  <p>
    <label for="user_adress_postcode">postcode:</label>
    <%= form.text_field :postcode, :size => 40 %>
  </p>
  <p>
    <label for="user_adress_city">City:</label>
    <%= form.text_field :city, :size => 40 %>
  </p>
<% end %>

<legend>Your payment details:</legend>
<% form_for :user_account do |form| %>
  <p>
    <label for="user_account_bank">credit institution:</label>
    <%= form.text_field :bank, :size => 40 %>
  </p>
  <p>
    <label for="user_account_bank_code">bank code:</label>
    <%= form.text_field :bank_code, :size => 40 %>
  </p>
  <p>
    <label for="user_account_account_number">account number:</

label>
<%= form.text_field :account_number, :size => 40 %>


<% end %>

<%= submit_tag “Register”, :class => “submit” %>

This creates 3 forms, but no submit tag in any of them.

Try using this:

form_for :user, @user, :url => {:action => :new} do |form|
#…your fields for user

fields_for :user_address, @user_address do |fields|
#…your fields for user_adress in the following form:
# fields.textarea (arguments)
end

fields_for :user_account, @user_account do |fields|
#same as for user_adress
end

<%= submit_tag “Register”, :class => “submit” %>
end

:user is the class of the object of interest
@user is an actual instance (which could have another name like
@new_user)
:url points the form to it’s target

same for the fields_for, but subforms do not get a target.

Have Fun
Skade

there’s also a problem in my controller. Neither does it save anything
to the database nor validate the models.

The template is register.rhtml. I wrote it as you said.

def register
@user = User.new
end

def new
if @user.save
@user.adress = @user_adress
@user.account = @user_account
flash[:notice] = ‘Registration was successful.’
redirect_to :action => ‘index’
else
render :action => ‘register’
end
end

I forgot to say that the relations are dependent.

And not everyone does have an account. So, if there’s nothing in the
account field, the account shouldn’t be saved.

Martin Luy wrote:

there’s also a problem in my controller. Neither does it save anything
to the database nor validate the models.

The template is register.rhtml. I wrote it as you said.

def register
@user = User.new
end

def new
if @user.save
@user.adress = @user_adress
@user.account = @user_account
flash[:notice] = ‘Registration was successful.’
redirect_to :action => ‘index’
else
render :action => ‘register’
end
end

Please consider that all Rails operations are stateless. You need to
instantiate a new User in def new. You will find the contents of the
form via params(:user).

Try:

def new
@user = User.new(params(:user))
@user.address.build(params(:user_adress))
@user.account.build(params(:user_account))
if @user.save!
flash[:notice] = ‘Registration was successful.’
redirect_to :action => ‘index’
else
render :action => ‘register’
end
end

I hope, you get the point, i can’t check the code right now.

Martin Luy wrote:

I forgot to say that the relations are dependent.

And not everyone does have an account. So, if there’s nothing in the
account field, the account shouldn’t be saved.

class User < ActiveRecord::Base
validates_associated :account, :address
end

Thanks for your help, I got to the following working code. 2 more
questions after the code.

In the controller:

def register
@user = User.new(params[:user])
@user.time_of_registration = Time.now
@user.user_adress = UserAdress.new(params[:user_adress])
@user.user_account = UserAccount.new(params[:user_account])
if request.post? and @user.save
flash[:notice] = ‘Registration was successful.’
redirect_to :action => ‘login’
end
end

register.rhtml:

<%= error_messages_for ‘user’ %>

Please enter your data:
<% form_for :user, @user do |form| %>
  <p>
    <label for="user_first_name">First name:</label>
    <%= form.text_field :first_name, :size => 40 %>
  </p>
  ...

  <% fields_for :user_adress, @user_adress do |fields| %>
    ...
  <% end %>

  <p>If you want to pay using debit, please enter your bank

account:


<% fields_for :user_account, @user_account do |fields| %>


credit institution:
<%= fields.text_field :bank, :size => 40 %>



bank code:
<%= fields.text_field :bank_code, :size => 40 %>



account number:</
label>
<%= fields.text_field :account_number, :size => 40 %>


<% end %>
  <%= submit_tag "Register", :class => "submit" %>

<% end %>

The user model:

class User < ActiveRecord::Base

has_one :user_adress, :dependent => true
has_one :user_account, :dependent => true

validates_associated :user_account, :user_adress

end

The account model:

class UserAccount < ActiveRecord::Base
belongs_to :user

validates_presence_of :bank, :bank_code, :account_number

validates_numericality_of …
validates_inclusion_of …
validates_format_of …
end

Questions:

Validation of user_account and user_adress looks like “User adress is
invalid”. I would like to show the errors for the children classes
explicitly.

How can I change “validate_presence_of” in UserAccount so that either
all or no fields are entered?

Thanks,
Luma