Hi -  Very new to RoR.  I have looked around at different strategies
for handling shipping and billing addresses for an e-commerce
applications.  What I am trying to do is to have a user registration
form where the user need to also fill out the default shipping
address.  Ultimately, I would like for the users to be able to add
additional shipping address and billing addresses.

I am sort of going down the path outlined by ryanb's here and using
Single Table Inheritance where the shipping address and billing
address inherits from address class.  Is this the best approach?

ryanb suggested something along the lines below:

    Customer
    has_many :addresses
    has_many :orders

    Address
    belongs_to :customer

    Order
    belongs_to :customer
    belongs_to :billing_address #...
    belongs_to :shipping_address #...

Is this an instance where I need to use both STI and polymorphic
association?

Can someone walk through an example of what is needed to do this or a
strategy to accomplish this?

Here is what I have so far for the registration form:
************************************************
<% title "User Registration" %>

<div id="registration_leftcol">
  <h1>Why Sign Up?</h1>
    <ul>
    <li>Faster checkout</li>
    <li>Track your orders</li>
    <li>View your order history</li>
    <li>Receive email updates</li>
    </ul>

  <p>
    <b>Already registered?  <%= link_to 'Login here!', login_path %></
b>
  </p>
</div>
<div id="registration_rightcol">
  <h1>Your Info</h1>
  <% form_for(@user) do |f| %>
    <%= f.error_messages %>
    <%= render :partial => 'form', :locals => { :f => f } %>

    <%= render :partial => "addresses/address", :collection =>
@user.addresses %>
    <p>
    <%=  image_submit_tag("/images/Register Button.jpg") %>
    </p>
  <% end %>
</div>
************************************************

I haven't created the order.rb model yet, but ryanb did suggest making
sure that...

    "The billing_address_id column would go in the orders table. Same
with the shipping."

Is this the only table in the database that would contain this
column?  Should they also exist in the address table or is this
handled by Rails through the type column?  All so very confusing.
Here's my current code but I'm certain I'm missing some key concepts
here.  I am providing some of the code below. Any help would be
greatly appreciated.

users_controller.rb
************************************************
class UsersController < ApplicationController
  # GET /users
  # GET /users.xml

  before_filter :require_no_user, :only => [:new, :create]
  before_filter :require_user, :only => [:show, :edit, :update]

  @title = 'User Registration'

  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
    end
  end

  # GET /users/1
  # GET /users/1.xml
  def show
    #...@user = User.find(params[:id])
    @user = @current_user

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @user }
    end
  end

  # GET /users/new
  # GET /users/new.xml
  def new
    @user = User.new
    @user_session = UserSession.new
    @user.addresses.build

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @user }
    end
  end

  # GET /users/1/edit
  def edit
  #  @user = User.find(params[:id])
  @user = @current_user
  end

  # POST /users
  # POST /users.xml
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        flash[:notice] = 'Registration successful.'
        format.html { redirect_to(@user) }
        format.xml  { render :xml => @user, :status
=> :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status
=> :unprocessable_entity }
      end
    end
  end

  # PUT /users/1
  # PUT /users/1.xml
  def update
    #  @user = User.find(params[:id])
    @user = @current_user

    respond_to do |format|
      if @user.update_attributes(params[:user])
        flash[:notice] = 'Account was successfully updated.'
        format.html { redirect_to(@user) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @user.errors, :status
=> :unprocessable_entity }
      end
    end
  end

  # DELETE /users/1
  # DELETE /users/1.xml
  def destroy
    @user = User.find(params[:user])
    @user.destroy

    respond_to do |format|
      format.html { redirect_to(users_url) }
      format.xml  { head :ok }
    end
  end
end
************************************************

user.rb model:
************************************************
class User < ActiveRecord::Base
  acts_as_authentic
  has_many :addresses
  accepts_nested_attributes_for :addresses, :allow_destroy => true

  def address_attributes=(address_attributes)
    address_attributes.each do |attributes|
      addresses.build(attributes)
    end
  end

How do I make the default registration address be the default
shipping_address?  I am using address here but should it be
shipping_address?  Should I use a hidden field to set the type and
modify the create section of the code?
************************************************

addresses_controller.rb
************************************************
class AddressesController < ApplicationController
  # GET /addresses
  # GET /addresses.xml

  def index
    @addresses = Address.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @addresses }
    end
  end

  # GET /addresses/1
  # GET /addresses/1.xml
  def show
    @address = Address.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @address }
    end
  end

  # GET /addresses/new
  # GET /addresses/new.xml
  def new
    @address = Address.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @address }
    end
  end

  # GET /addresses/1/edit
  def edit
    @address = Address.find(params[:id])
  end

  # POST /addresses
  # POST /addresses.xml
  def create
    @address = Address.new(params[:address])

    respond_to do |format|
      if @address.save
        flash[:notice] = 'Address was successfully created.'
        format.html { redirect_to(@address) }
        format.xml  { render :xml => @address, :status
=> :created, :location => @address }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @address.errors, :status
=> :unprocessable_entity }
      end
    end
  end

  # PUT /addresses/1
  # PUT /addresses/1.xml
  def update
    @address = Address.find(params[:id])

    respond_to do |format|
      if @address.update_attributes(params[:address])
        flash[:notice] = 'Address was successfully updated.'
        format.html { redirect_to(@address) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @address.errors, :status
=> :unprocessable_entity }
      end
    end
  end

  # DELETE /addresses/1
  # DELETE /addresses/1.xml
  def destroy
    @address = Address.find(params[:id])
    @address.destroy

    respond_to do |format|
      format.html { redirect_to(addresses_url) }
      format.xml  { head :ok }
    end
  end
end
************************************************

address.rb model
************************************************
class Address < ActiveRecord::Base
  belongs_to :user
end
************************************************

billing_address.rb
************************************************
class BillingAddress < Address
end
************************************************

shipping_address.rb
************************************************
class ShippingAddress < Address
end
************************************************

--

You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=.


Reply via email to