Forum: Ruby on Rails RE: Should controllers be "smart"?

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.
1f840b624a948a3f39299af25620121b?d=identicon&s=25 Ross Dawson (Guest)
on 2006-05-05 08:44
(Received via mailing list)
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
B29105598b6464efc13b04cb445efa85?d=identicon&s=25 Chris Bruce (Guest)
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
31ae911dd0fe0ee0b81519d6d2627886?d=identicon&s=25 Gravy Face (gravyface)
on 2006-05-05 19:38
(Received via mailing list)
On 5/5/06, Chris Bruce <cbruce@sleeter.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.
42172acdf3c6046f84d644cb0b94642c?d=identicon&s=25 Pat Maddox (pergesu)
on 2006-05-05 23:41
(Received via mailing list)
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
This topic is locked and can not be replied to.