Forum: Ruby on Rails 3 models in 1 template

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
70dc5b6a5bf97779ee34d2865539f50b?d=identicon&s=25 Martin Luy (luma)
on 2007-04-15 17:51
(Received via mailing list)
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.


<div class="shop-form">

  <%= error_messages_for 'user' %>
  <%= error_messages_for 'user_adress' %>
  <%= error_messages_for 'user_account' %>

  <fieldset>
    <legend>Please enter your data: </legend>

    <% 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  %>
      </p>
      <p>
        <label for="user_email">email:</label>
        <%= form.text_field :email, :size => 40 %>
      </p>
      <p>
        <label for="user_username">username:</label>
        <%= form.text_field :username, :size => 40 %>
      </p>
      <p>
        <label for="user_password">password:</label>
        <%= form.password_field :password, :size => 40 %>
      </p>
      <p>
        <label for="user_password_confirmation">passwort
confirmation:</label>
        <%= form.password_field :password_confirmation, :size => 40 %>
      </p>
    <% end %>

  <br/>

    <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 %>

  <br/>

    <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 %>
      </p>
    <% end %>

  <br/>

  <%= submit_tag "Register", :class => "submit" %>
  </fieldset>

</div>
D1f1c20467562fc1d8c8aa0d328def62?d=identicon&s=25 Florian Gilcher (skade)
on 2007-04-15 18:20
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
70dc5b6a5bf97779ee34d2865539f50b?d=identicon&s=25 Martin Luy (luma)
on 2007-04-16 01:20
(Received via mailing list)
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
70dc5b6a5bf97779ee34d2865539f50b?d=identicon&s=25 Martin Luy (luma)
on 2007-04-16 01:33
(Received via mailing list)
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.
D1f1c20467562fc1d8c8aa0d328def62?d=identicon&s=25 Guest (Guest)
on 2007-04-16 01:35
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.
D1f1c20467562fc1d8c8aa0d328def62?d=identicon&s=25 Guest (Guest)
on 2007-04-16 01:38
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
70dc5b6a5bf97779ee34d2865539f50b?d=identicon&s=25 Martin Luy (luma)
on 2007-04-17 00:22
(Received via mailing list)
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:

<div class="shop-form">

  <%= error_messages_for 'user' %>

  <fieldset>
    <legend>Please enter your data: </legend>

    <% 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: </p>
      <% fields_for :user_account, @user_account do |fields| %>
        <p>
          <label for="user_account_bank"> credit institution:</label>
          <%= fields.text_field :bank, :size => 40 %>
        </p>
        <p>
          <label for="user_account_bank_code">bank code:</label>
          <%= fields.text_field :bank_code, :size => 40 %>
        </p>
        <p>
          <label for="user_account_account_number">account number:</
label>
          <%= fields.text_field :account_number, :size => 40 %>
        </p>
      <% end %>

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

    <% end %>

  </fieldset>

</div>


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
This topic is locked and can not be replied to.