<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>OnRails.org: Mapping Rails Errors to Flex Fields.</title>
    <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Ruby On Rails and related matters.</description>
    <item>
      <title>Mapping Rails Errors to Flex Fields.</title>
      <description>&lt;p&gt;&lt;img src="http://onrails.org/files/20070306_signup_errors.jpg" border="0" height="164" width="528" alt="20070306_signup_errors.jpg" align="center" /&gt;&lt;/p&gt;


	&lt;p&gt;We extended the &lt;a href="wheelerstreet"&gt;com.wheelerstreet.utils.ValidatorForm&lt;/a&gt; to add support for Rails Errors. Saving a form is a two step process. First, client side validation,  the Signup button only gets enabled if the form is valid from a client side point of view. Step 2, server side validation,  the user press the signup button and invokes the Rails UserController#create method&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;class UsersController &amp;lt; ApplicationController
  def create
    @user = User.new(params[:user])
    respond_to do |format|
      if @user.save
        self.current_user = @user
        format.xml  { head :created }
      else
        format.xml  { render :xml =&amp;gt; @user.errors.to_xml(:dasherize =&amp;gt; false) }       end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If saving the user fails then Rails return the xml version of the errors:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;@user.errors.to_xml(:dasherize =&amp;gt; false)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now we need a generic way to deal with these errors. We created the Flex RailsErrors class to manage the returned xml. And we created the RailsValidationForm  that extends the com.wheelerstreet.utils.ValidatorForm. The RailsValidationForm class can be bound to a RailsErrors instance. So the result handler of the Flex Cairngorm Flex SignupCommand we just set the errors on the model locatorL&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;    var errors:RailsErrors = new RailsErrors(data.result as XML);
    MySpyderModelLocator.getInstance().signupErrors = errors;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The signup.mxml page contains the following signup form&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;lt;mx:Canvas 
        xmlns:mx=&amp;quot;http://www.adobe.com/2006/mxml&amp;quot; 
        xmlns:rails=&amp;quot;org.onrails.rails.*&amp;quot;
&amp;gt;

 &amp;lt;mx:Panel x=&amp;quot;162&amp;quot; y=&amp;quot;64&amp;quot; title=&amp;quot;Signup - Your Account Details.&amp;quot;&amp;gt;             
     &amp;lt;!-- Instance of org.onrails.rails.RailsValidationForm  --&amp;gt;
     &amp;lt;rails:RailsValidationForm 
            id=&amp;quot;submitForm&amp;quot; 
            defaultButton=&amp;quot;{signupButton}&amp;quot; 
            validators=&amp;quot;{validators}&amp;quot; 
            fieldMap=&amp;quot;{{Email:email, Password:password}}&amp;quot;
            railsErrors=&amp;quot;{MySpyderModelLocator.getInstance().signupErrors}&amp;quot;                    
                 x=&amp;quot;98&amp;quot; y=&amp;quot;89&amp;quot;&amp;gt;
              &amp;lt;mx:FormItem label=&amp;quot;email&amp;quot;&amp;gt;
                       &amp;lt;mx:TextInput id=&amp;quot;email&amp;quot; /&amp;gt;
              &amp;lt;/mx:FormItem&amp;gt;
              &amp;lt;mx:FormItem label=&amp;quot;Password&amp;quot;&amp;gt;
                       &amp;lt;mx:TextInput id=&amp;quot;password&amp;quot; displayAsPassword=&amp;quot;true&amp;quot; /&amp;gt;
              &amp;lt;/mx:FormItem&amp;gt;
              &amp;lt;mx:FormItem label=&amp;quot;Confirmation&amp;quot;&amp;gt;
                       &amp;lt;mx:TextInput id=&amp;quot;passwordConfirmation&amp;quot; displayAsPassword=&amp;quot;true&amp;quot; /&amp;gt;
              &amp;lt;/mx:FormItem&amp;gt;
              &amp;lt;mx:Button id=&amp;quot;signupButton&amp;quot; label=&amp;quot;Signup &amp;amp;gt;&amp;amp;gt;&amp;quot; click=&amp;quot;signup()&amp;quot; enabled=&amp;quot;{MySpyderModelLocator.getInstance().signupButtonEnabled}&amp;quot;/&amp;gt;
     &amp;lt;/rails:RailsValidationForm&amp;gt;
 &amp;lt;/mx:Panel&amp;gt;
 &amp;lt;rails:RailsErrorBox x=&amp;quot;487&amp;quot; y=&amp;quot;64&amp;quot; width=&amp;quot;301&amp;quot; height=&amp;quot;178&amp;quot;
     errorMessage=&amp;quot;errors prohibited this new account to be created&amp;quot;
     errors=&amp;quot;{MySpyderModelLocator.getInstance().signupErrors}&amp;quot;  
     visible=&amp;quot;{MySpyderModelLocator.getInstance().signupErrors &amp;amp;amp;&amp;amp;amp; MySpyderModelLocator.getInstance().signupErrors.hasErrors()}&amp;quot;
 /&amp;gt;
&amp;lt;/mx:Canvas&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The RailsErrorBox just displays the text of all error messages and is only visible if there are any Rails errors.&lt;/p&gt;


	&lt;p&gt;Now all the magic happens in the  org.onrails.rails.RailsValidationForm railsErrors setter.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public function set railsErrors(errors:RailsErrors):void {
    _railsErrors = errors;
    if (_railsErrors==null || !_railsErrors.hasErrors()) {
        resetErrors();
    } else {
        for each (var field:String in _railsErrors.fields) {
            if (_fieldMap[field]) 
                _fieldMap[field].errorString = field + ' ' + _railsErrors.getFieldErrors(field).join(', ');
        }                
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  

	&lt;p&gt;The key is to associate the Rails error message with the field is simply to set the errorString on the field.&lt;/p&gt;


	&lt;p&gt;I just created this code this morning at breakfast so it&amp;#8217;s really a work in progress. For instance it doesn&amp;#8217;t support Rails attributes that are more than one word. But this goes hand in hand with the ActiveResourceClient and can be useful I hope to others trying to integrate Rails and Flex. So we will create a Google project and post the RailsErrors and RailsValidationForm.&lt;/p&gt;</description>
      <pubDate>Tue, 06 Mar 2007 18:36:30 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:4c95fd45-08a8-4d95-ad24-d4927ce29ec5</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields</link>
      <category>Ruby On Rails</category>
      <category>Flex</category>
    </item>
    <item>
      <title>"Mapping Rails Errors to Flex Fields." by Daniel Wanja</title>
      <description>&lt;p&gt;The original article was on &lt;a href="http://blog.wheelerstreet.com/"&gt;http://blog.wheelerstreet.com/&lt;/a&gt;?p=123. There is a Flex demo application in the article on which you can do a view source. The source is visible here &lt;a href="http://blog.wheelerstreet.com/code/formValidator/srcview/index.html"&gt;http://blog.wheelerstreet.com/code/formValidator/srcview/index.html&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 28 Nov 2007 22:15:38 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:67c908d7-8b5c-44a3-825b-f3f6141094c3</guid>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields#comment-2896</link>
    </item>
    <item>
      <title>"Mapping Rails Errors to Flex Fields." by R Sherman</title>
      <description>&lt;p&gt;The wheelerstreet article link is broken.  Any chance of that bieng archived somewhere?&lt;/p&gt;</description>
      <pubDate>Wed, 28 Nov 2007 22:07:55 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3d095eeb-4d2b-4685-ae78-21cdba097aae</guid>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields#comment-2895</link>
    </item>
    <item>
      <title>"Mapping Rails Errors to Flex Fields." by Daniel Wanja</title>
      <description>&lt;p&gt;Hi Herman,&lt;/p&gt;


	&lt;p&gt;You can get the RailsErrors class here &lt;a href="http://nouvelles-solutions.com/onrails/activeresourceclient/ActiveResourceClient.zip"&gt;http://nouvelles-solutions.com/onrails/activeresourceclient/ActiveResourceClient.zip&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This zip file contains the following files:&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://nouvelles-solutions.com/onrails/activeresourceclient/ActiveResourceClient.mxml"&gt;ActiveResourceClient.mxml&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://nouvelles-solutions.com/onrails/activeresourceclient/FixtureResource.as"&gt;FixtureResource.as&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://nouvelles-solutions.com/onrails/activeresourceclient/RailsErrorBox.mxml"&gt;RailsErrorBox.mxml&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://nouvelles-solutions.com/onrails/activeresourceclient/RailsErrors.as"&gt;RailsErrors.as&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://nouvelles-solutions.com/onrails/activeresourceclient/RailsValidationForm.as"&gt;RailsValidationForm.as&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Use at your own risk ;-)&lt;/p&gt;</description>
      <pubDate>Wed, 22 Aug 2007 13:36:35 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:bd1fd6ff-1edc-4431-b00b-ec18ef2e6aa7</guid>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields#comment-2589</link>
    </item>
    <item>
      <title>"Mapping Rails Errors to Flex Fields." by Herman Jansen</title>
      <description>&lt;p&gt;Nice work. I don&amp;#8217;t seem te be able to find the RailsErrors class though. Is it possible to post it also. Thanks.&lt;/p&gt;</description>
      <pubDate>Wed, 22 Aug 2007 13:20:30 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:792cb634-dce1-4b2c-92ee-4839ddf3553f</guid>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields#comment-2588</link>
    </item>
    <item>
      <title>"Mapping Rails Errors to Flex Fields." by Dan Milliron</title>
      <description>&lt;p&gt;This is a Flex-only solution, however, because the Rails server sends a 200/OK status code even when there is an error.  Ideally, the Rails server would send the error messages in XML, as it is doing in this article, but also send an error status code such as 400/Bad-Request.&lt;/p&gt;


	&lt;p&gt;That way, the Rails server works with non-Flex clients.&lt;/p&gt;


	&lt;p&gt;Does anyone have a solution for sending non-success (non 2xx) status codes to Flex along with error messages?&lt;/p&gt;</description>
      <pubDate>Tue, 22 May 2007 05:42:04 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:abb7f4b4-afe1-406d-9154-d02ffd3f59f5</guid>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields#comment-1581</link>
    </item>
    <item>
      <title>"Mapping Rails Errors to Flex Fields." by Daniel Wanja</title>
      <description>&lt;p&gt;Thanks for feedback. I will have to play with that as I was strungling finding how to trigger a Fault and pass information back to the Flex app. So maybe thats the anwser. I will play with it once I am back from the 360Flex conference.&lt;/p&gt;</description>
      <pubDate>Wed, 07 Mar 2007 15:49:53 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:23268d09-2d53-43cc-a3cd-03e6eaae2df9</guid>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields#comment-287</link>
    </item>
    <item>
      <title>"Mapping Rails Errors to Flex Fields." by ilya Devèrs</title>
      <description>&lt;p&gt;The observer also disapeared, so here i try again with textile&amp;#8230; [crossing fingers]&lt;/p&gt;


	&lt;p&gt;I set up my rails models with validations.&lt;/p&gt;


	&lt;p&gt;I then call a save! in my service (as this throws an error). This error triggers the Fault method in my cairngorm command:&lt;/p&gt;


&lt;pre&gt;
public function fault(info:Object):void
{
  try{
    var i:FaultEvent = FaultEvent(info);
    PoolManModel.getInstance().serverValidationMessages = ArrayUtil.toArray(i.fault.faultString);
  } catch(error:Error) {
    Alert.show("ouch:" + error.message, "mas problemas");
  }
}
&lt;/pre&gt;

The next part is a remote validator class:
&lt;pre&gt;
package view
{
    import mx.validators.Validator; 
    import mx.validators.ValidationResult;
    import com.adobe.cairngorm.model.ModelLocator;
    import models.PoolManModel; 
    public class RemoteValidator extends Validator { 

        // Define Array for the return value of doValidation(). 
        private var results:Array; 

        public function RemoteValidator() { 
            // Call base class constructor. 
            super(); 
        } 

        // Define the doValidation() method. 
        override protected function doValidation(value:Object):Array { 
            results = super.doValidation(value);        
            // Return if there are errors. 
            if (results.length &amp;gt; 0) 
                return results; 

            var result:Array = new Array();
            var messages:Array = PoolManModel.getInstance().serverValidationMessages;
            for (var i:int=0; i &amp;lt; messages.length; i++){
                result.push(new ValidationResult(true, null, "NaN", messages.pop())); 
            }
            return result;
        } 
    } 
}
&lt;/pre&gt;

	&lt;p&gt;Now, how do we make sure the doValidation is triggered?&lt;/p&gt;


I add an observer (thanks Alex Uhlmann) to my view, here you see them side by side:
&lt;pre&gt;
&amp;lt;view:RemoteValidator id="userNameValidator"  source="{user_name}" property="text" required="true" /&amp;gt; 
&amp;lt;ac:ObserveValue handler="triggerRemoteValidator" source="{model.serverValidationMessages.length}" value="true"/&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;What do you think?&lt;/p&gt;</description>
      <pubDate>Tue, 06 Mar 2007 22:59:12 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:1b1e4737-1377-4f50-9958-e536e7199590</guid>
      <link>http://onrails.org/articles/2007/03/06/mapping-rails-errors-to-flex-fields#comment-283</link>
    </item>
  </channel>
</rss>
