Forum: Ruby on Rails Inconsistent REST behavior

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.
D57f8a6095df6b8a3aae2eeae014ccee?d=identicon&s=25 ncancelliere (Guest)
on 2009-06-02 13:09
(Received via mailing list)
Has anyone seen Rails save nested associations despite their being
invalid?

If I hit the site from a different Rails app (using ActiveResource)
and try to update the record so that the username is too short it
fails (as I expect) and adds an errors attribute to the object that I
can inspect.  The original account (and associated user and email
objects) is unaffected, as I'd expect.

Hitting the same exact URL with a raw HTTP/REST client and sending in
XML:

<?xml version="1.0" encoding="UTF-8"?>
<account>
  <id>1</id>
  <user>
    <birthdate>2010-01-05</birthdate>
    <username>soto</username>
  </user>
  <email>
    <address>sotom@here.net</address>
    <opt-in>true</opt-
in>
    <opt-in-ch1>false</opt-in-ch1>
  </email>
</account>

It gives me the expected 422 Unprocessible Entity error, which I
expect.  However it also saves user down as a null!  That I do not
expect.

My question is why does it correctly handle errors with ActiveResource
(eg. doesn't save anything down since their are validation problems)
but with a raw PUT request it saves with a null user object
(effectively killing the user).

# models

class User < ActiveRecord::Base
  belongs_to :account

  validates_length_of :username, :minimum => 6

end

class Account < ActiveRecord::Base

  has_one :user
  has_one :email

  has_many :account_entitlements
  has_many :entitlements, :through => :account_entitlements

  accepts_nested_attributes_for :user, :email

  def user=(params)
    update_attributes(:user_attributes => params)
  end

  def email=(params)
    update_attributes(:email_attributes => params)
  end

end

# controller

  def update
    @account = Account.find(params[:id])

    respond_to do |format|
      if @account.update_attributes(params[:account])
        flash[:notice] = 'Account was successfully updated.'
        format.html { redirect_to(@account) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @account.errors, :status
=> :unprocessable_entity }
      end
    end
  end
This topic is locked and can not be replied to.