I'd keep them separate User.register(...) is not called User.register_and_deliver_welcome_email(...) I try and factor each method so it has one simple task (laziness tends to get in the way). If your find that your repeating yourself then I'd create a higher level helper method such as User.register_and_deliver_welcome_email(...) Decoupling the email action from the registration action would provide greater flexibility in the model as Koz mentions it does all depend on individual requirements and/or tastes. Ross
on 2006-05-05 08:44
on 2006-05-05 18:55
Ok so how would the register method look in the following: User has_many :addresses validates_presence_of_one_address # <- Say some custom validation to require one address Address belongs_to :user validates_presence_of :address, :city, :state, :zip validate_zip_code # <- Say some custom validation to lookup zipcode Business RULE: User must have at least one address. Address must have valid zip code plus address, city, state, zip. My web form: Fields for User Information, including TWO addresses (one for shipping, and mailing). So according to the idea the model should have all business rules and logic... User.register should save the user info AND adresses, right? So what if an address validation fails. How does controller know which address failed, and what the errors. Can you show me how the User.register method would look in this case? Chris Ross Dawson wrote: > I'd keep them separate > > User.register(...) is not called > User.register_and_deliver_welcome_email(...) > > I try and factor each method so it has one simple task (laziness tends > to get in the way). If your find that your repeating yourself then I'd > create a higher level helper method such as > User.register_and_deliver_welcome_email(...) > > Decoupling the email action from the registration action would provide > greater flexibility in the model > > as Koz mentions it does all depend on individual requirements and/or > tastes. > > Ross
on 2006-05-05 19:38
On 5/5/06, Chris Bruce <email@example.com> wrote: > Ok so how would the register method look in the following: > validate_zip_code # <- Say some custom validation to lookup zipcode To me, things like zip code validation, email validation, etc. would be a Helper.
on 2006-05-05 23:41
Your register could save everything if you want it to. Just depends on how course-grained you want it to be. The real point is that even if you don't write a register method to handle everything, the business logic is still available entirely from the model. u = logged_in_user u.shipping_address = Address.new(params[:shipping]) u.billing_address = Address.new(params[:billing]) u.save Now obviously this snippet requires some code from the controller (it uses our helper method logged_in_user and params), but it's not coupled to the controller. You could open the console and set a billing address. You could write a standalone app that uses the model to do this. The controller is handling application logic - figuring out what objects to use, methods to call, order in which to call them - but the business logic belongs to the model. Finally, to answer your question about how to handle errors, it seems pretty simple to me. u = User.register(User.new(params[:user]), Address.new(params[:shipping]), Address.new(params[:billing]) if u.save redirect_to success_url else @shipping = u.shipping_address @billing = u.billing_address end class User belongs_to :shipping_address, :foreign_key => 'shipping_address', :class => :address belongs_to :billing_address, :foreign_key => 'billing_address', :class => :address validates_associated :shipping_address validates_associated :billing_address def self.register(u, shipping, billing) u.shipping = shipping u.billing = billing u end end Throw a validates_associated in your User model, which will validate the two addresses and add errors if validation fails. Then assign those to the instance variables, which will populate your forms and show any errors. My example SUCKS of course, to be passing in a user and then returning it, but I'm just trying to show you that you can write a coarse-grained register method and still use the nice rails error handling. Pat