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.
Martin L. (Guest)
on 2007-04-15 19: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>
Florian G. (Guest)
on 2007-04-15 20: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
Martin L. (Guest)
on 2007-04-16 03: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
Martin L. (Guest)
on 2007-04-16 03: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.
Guest (Guest)
on 2007-04-16 03: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.
Guest (Guest)
on 2007-04-16 03: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
Martin L. (Guest)
on 2007-04-17 02: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.