Newbie on Rails

Hello everyone.

Near the end of last week I’ve decided to get my hands on a project
that, unfortunately, has been lying around in my desk for a while now.

As with any other project I’ve elaborated my project plan, with all the
requirements, risks, issues, resources, etc. After that, I started my
quest to figure out which would be the best set of technologies for this
particular project.

This was when I became acquainted with Rails. I’ve heard about it
before, but never had the time to dig into it and check what exactly it
was.

On a first look Ruby seems like a weird language, after so many years of
programming in both PHP and Microsoft .Net’s C#, for web and desktop.
But, that should not be a problem. It’s a question of time. However,
after reading and exploring Ruby on Rails I found a couple of issues
that got me worried enough to post this message, on Ruby-Forum.com.
These are:

  • Over the time I’ve started developing websites using a set of design
    patterns and practices. For instance, I always develop one or more APIs,
    containing the business logic, which is implemented in all interfaces
    preventing me from duplicating all the business logic. Also,

  • I’ve noticed that Ruby on Rails imposes the MVC paradigm, which is
    good. But, as a newbie when it comes to real use of MVC, it seems like a
    limitation as I usually go for fine-grained URLS. For example, consider
    the following URL for the sample domain MySite.com:
    http://www.mysite.com/supplier/management/permissions/
    My clients came to love this kind of URLs. It let’s them know exactly
    where they are, without weird names. But how could this be implemented
    under the MVC paradigm? All the code would have to be under the supplier
    controller? What if there are 100 things to manage, as a supplier, with
    [say] 60 interfaces? Will all that code have to be in the supplier
    controller and model?

How could I implement something like I’ve always done in MVC? How can I
overcome my API problem?

All suggestions are welcomed.
Best regards.

Andrew S. wrote:

That is what MVC is all about. All the business logic for an object is
contained in the models, the controllers orchestrate the interactions
between the models and pass the results to the view.

Yes, but I rather have my business logic in an API than in a model. This
is because I just don’t know when I’ll need to reuse it.

It would be like developing an ASP.net all in one project. That’s rather
suicidal, from an application scalability / reusability point of view.

Check out the config/routes.rb file - this is where these URLs are
defined.

I’ve seen this file, but I haven’t tryed to “hammer” it just yet :wink:

Nested routes are your answer.

I’ll take a look at that. Could you advance me on how would it work for
my sample URL (http://www.mysite.com/supplier/management/permissions/)?

I would need a route for the /{controller} with a nested route for the
/{controller}/{sub-module / sub-controller}/{action}, which in turn
would point to a controller file called, for example,
supplier_management_permissions_controller.rb?

I assume your “API problem” is limited to the URLs (for you not
mentioned anything else), but you might want to checkout RESTful
resources which will enable a complete REST interface for free.

That’s one way to solve it. I could have an app with REST services, and
another app consuming it. However, I’m yet to determine if the overhead
would be something that I’m interested just yet. Perhaps developing a
library, written in Ruby, and consumed by the Ruby on Rails app would be
another way to do it. However, I suppose that the lib would miss all the
RoR fun :wink:

Diogo D. wrote:

These are:

  • Over the time I’ve started developing websites using a set of design
    patterns and practices. For instance, I always develop one or more APIs,
    containing the business logic, which is implemented in all interfaces
    preventing me from duplicating all the business logic. Also,

That is what MVC is all about. All the business logic for an object is
contained in the models, the controllers orchestrate the interactions
between the models and pass the results to the view.

  • I’ve noticed that Ruby on Rails imposes the MVC paradigm, which is
    good. But, as a newbie when it comes to real use of MVC, it seems like a
    limitation as I usually go for fine-grained URLS. For example, consider
    the following URL for the sample domain MySite.com:
    http://www.mysite.com/supplier/management/permissions/
    My clients came to love this kind of URLs. It let’s them know exactly
    where they are, without weird names. But how could this be implemented
    under the MVC paradigm?

Check out the config/routes.rb file - this is where these URLs are
defined.

All the code would have to be under the supplier
controller? What if there are 100 things to manage, as a supplier, with
[say] 60 interfaces?

Nested routes are your answer.

Will all that code have to be in the supplier
controller and model?

How could I implement something like I’ve always done in MVC? How can I
overcome my API problem?

I assume your “API problem” is limited to the URLs (for you not
mentioned anything else), but you might want to checkout RESTful
resources which will enable a complete REST interface for free.

Andrew S. wrote:

That is what MVC is all about. All the business logic for an object is
contained in the models, the controllers orchestrate the interactions
between the models and pass the results to the view.

Yes, but I rather have my business logic in an API than in a model. This
is because I just don’t know when I’ll need to reuse it.

That got me stumped a bit when I started (and I am still starting) the
learning process with RoR. However, I realized that even with a “man
in the middle” interface, such as the old “file from the mainframe
uploaded to a website” interaction - business logic can still be
contained in my model, even if I am simply modeling a file, not a
database. It’s as if you decide how big the fields need to be (fixed
length), or how one database value requires a certain set of
characters, in a container that “wraps” itself around the eventual
output. It has worked really well so far, especially in making me
think in the idea of containers and such.

Also, if I know I have a model called “BankCoUpload” (or whatever) - I
know that, from anywhere else, I can stuff data through that model/
controller and meet whatever spec was created for that purpose.

Diogo D. wrote:

I’ll take a look at that. Could you advance me on how would it work for
my sample URL (http://www.mysite.com/supplier/management/permissions/)?

I would need a route for the /{controller} with a nested route for the
/{controller}/{sub-module / sub-controller}/{action}, which in turn
would point to a controller file called, for example,
supplier_management_permissions_controller.rb?

You seem to have three models operating here - suppliers, management,
and permissions.
These might look like the following:

class Supplier < Activerecord::Base
end

class Management < Activerecord::Base
has_many :permissions
end

class Permission < Activerecord::Base
belong_to :management
end

Although, you might want to subclass Management from another model, say
Users?

The routes then might look like this:

map.resources :suppliers do |supplier|
supplier.resources :management do |manager|
manager.resources ;permissions
end
end

or something like:

map.resources :suppilers, :has_many => :managers
map.resources :managers, :has_many => :permissions

(untested and you may want to fiddle with the code to get the routes you
are looking for).

Run “rake routes” at the terminal to get a list of the routes table.

I assume your “API problem” is limited to the URLs (for you not
mentioned anything else), but you might want to checkout RESTful
resources which will enable a complete REST interface for free.

That’s one way to solve it. I could have an app with REST services, and
another app consuming it. However, I’m yet to determine if the overhead
would be something that I’m interested just yet. Perhaps developing a
library, written in Ruby, and consumed by the Ruby on Rails app would be
another way to do it. However, I suppose that the lib would miss all the
RoR fun :wink:

Sticking to the 7 methods in the controllers for each model and hooking
them together with routes will give you all you need. Although,
depending on your requirements, you may need to create one REST
application that services others.

Andrew

@Diogo:
I think you’ll need to be more specific about what you mean by the
“API problem” before you can get really helpful comments on that.

Ruby does not have the same type of interfaces that you’ve come to
rely on C# and similar languages. It’s much more reliant on duck-
typing and, used effectively, you can achieve a similar result.
Specifically, you don’t worry about whether or not a class implements
a specific interface; from a duck-typing/Ruby perspective you really
want to know if it performs some method. And if that’s your
objective, you just ask it:

an_instance.respond_to?(:some_interesting_thing_to_do)

You can then move on gracefully if your object does not respond to the
method in question or raise an exception if you prefer exception
handling for that type of thing.

You will also want to look into using ‘modules’. Modules fall
somewhere between interfaces and abstract classes on the C# scale.
They allow you to craft a specific interface, interact with private
state of the class, but do so at a completely abstract level. For
example, in one application I’ve built I have things like addresses
and phone numbers and the like that are valid for a particular date
range. I needed to allow the user to say ‘replace the home address/
phone with X value starting on Y date’. To handle that I wrote a
module that dealt only with the activation and deactivation dates and
provided a simple api for asking whether the instance that I found was
the currently active on, or to find the one that was active on a
specific date. It also enforced the rules about preventing two
objects from being active at the same time. What was nice was that
the module gave me the api (interface) but I could program it with
real instance/state information (abstract class) but without caring
what class I was dealing with or imposing a requirement that the
classes themselves implement the method (interface).

The MVC framework may not be a huge help to you if you’ve been a
particularly disciplined OO developer. Unfortunately I’ve done enough
project where I was always perfectly disciplined and everyone else
messed things up. :slight_smile: MVC is a good guide for everyone because it
helps enforce proper separation. It’s the same type of n-tiered
solution that .net developers always want until the drag-and-droppers
get involved.

As for the URL issue, there are several ways to get to the kinds of
urls that you want. In fact, one of the reasons that many people like
rails is for the same kind of clean urls that you’ve apparently been
using. There are a few things that will be helpful for you to achieve
those urls. First, you can use namespacing. This is similar to what
you’d do in .net in that it allows you to segment the application and
group similar concerns within the overall solution. What’s as nice
(or better) is that the organizational principle gets reflected in the
url as well. That is, all of your admin or management views would be
grouped together in the project AND the url would include /admin or /
management as you’ve described.

The default routing, particularly nested routing, would help you go
even further. By convention, rails generates routes that follow a
format of

collection_name/[token]

Which is to say all your customers could be retrieved by hitting /
customers, but a specific customer would be found by hitting /
customers/1234 (where, by convention, 1234 is the id of the
customer). One of the nice things that you can do, though, is to
override a method specifically used by the routing so that your url
instead looks like

/customers/pragmatic_programmers

where pragmatic_programmers is the name of the customer, downcased and
with underscores added. Your customers might like that even more
since they could bookmark ‘frequent flyers’.

Nested routes are similar. The ‘nesting’ comes in the fact that you’d
get /parent_collection/[parent_token]/child_collection[token]. The
format can be really handy when you’re adding a new item to a child
collection because the identifier is passed along to the controller
that handles the children.

It’s also worth noting that you can completely bypass the RESTful
routing if you want. The routes.rb file permits several ways to add a
url to the route map so you can continue to use the same kinds of urls
that you are using today. In short you give the route a name,
describe it’s pattern (perhaps with a string), and then tell it what
controller and action (method) should respond. The routing system
even permits regex matching, making it easy to provide, for example,
dated blog entries that conform to something like /posts/2008/may.

As a reformed C# guy myself I can say that I never look back and wish
I had the ‘opportunity’ to select just the right collection of objects
and configurations from among the 25K+ that MS has to offer. In fact,
I’m thankful every day that I hooked up my friend to do contract work
on a legacy project so I can stay .net free for yet another day!

Feel free to contact me off line if you want to talk any more
specifics.

On May 11, 4:43 pm, Diogo D. [email protected]

AndyV, first of all, thanks for your enlightning reply.

Back to the topic, let me reply to your post by splitting it in smaller
quotes.

AndyV wrote:

@Diogo:
I think you’ll need to be more specific about what you mean by the
“API problem” before you can get really helpful comments on that.

Ruby does not have the same type of interfaces that you’ve come to
rely on C# and similar languages. It’s much more reliant on duck-
typing and, used effectively, you can achieve a similar result.
Specifically, you don’t worry about whether or not a class implements
a specific interface; from a duck-typing/Ruby perspective you really
want to know if it performs some method. And if that’s your
objective, you just ask it:

an_instance.respond_to?(:some_interesting_thing_to_do)

You can then move on gracefully if your object does not respond to the
method in question or raise an exception if you prefer exception
handling for that type of thing.

Yes, I could do that. It just feels strange that there’s no real
contract enforced by design, only at runtime by the “host / invoker”. In
practice it boils down to a matter of principles and vicious programming
styles, where you apply the same design patterns over and over,
throughout the countless projects.

You will also want to look into using ‘modules’. Modules fall
somewhere between interfaces and abstract classes on the C# scale.
They allow you to craft a specific interface, interact with private
state of the class, but do so at a completely abstract level. For
example, in one application I’ve built I have things like addresses
and phone numbers and the like that are valid for a particular date
range. I needed to allow the user to say ‘replace the home address/
phone with X value starting on Y date’. To handle that I wrote a
module that dealt only with the activation and deactivation dates and
provided a simple api for asking whether the instance that I found was
the currently active on, or to find the one that was active on a
specific date. It also enforced the rules about preventing two
objects from being active at the same time. What was nice was that
the module gave me the api (interface) but I could program it with
real instance/state information (abstract class) but without caring
what class I was dealing with or imposing a requirement that the
classes themselves implement the method (interface).

I see.

The MVC framework may not be a huge help to you if you’ve been a
particularly disciplined OO developer. Unfortunately I’ve done enough
project where I was always perfectly disciplined and everyone else
messed things up. :slight_smile: MVC is a good guide for everyone because it
helps enforce proper separation. It’s the same type of n-tiered
solution that .net developers always want until the drag-and-droppers
get involved.

Not a huge help at all… I’m a MVC beginner. Therefore, I can only hope
that what I now consider to be a feature that complicates what was
simple will become a plus over time. Hard to forsee such future, just
yet :slight_smile:

As for the URL issue, there are several ways to get to the kinds of
urls that you want. In fact, one of the reasons that many people like
rails is for the same kind of clean urls that you’ve apparently been
using. There are a few things that will be helpful for you to achieve
those urls. First, you can use namespacing. This is similar to what
you’d do in .net in that it allows you to segment the application and
group similar concerns within the overall solution. What’s as nice
(or better) is that the organizational principle gets reflected in the
url as well. That is, all of your admin or management views would be
grouped together in the project AND the url would include /admin or /
management as you’ve described.

Sounds like a very interesting and promissing thing. Will have to dig
into that.

The default routing, particularly nested routing, would help you go
even further. By convention, rails generates routes that follow a
format of

collection_name/[token]

Which is to say all your customers could be retrieved by hitting /
customers, but a specific customer would be found by hitting /
customers/1234 (where, by convention, 1234 is the id of the
customer). One of the nice things that you can do, though, is to
override a method specifically used by the routing so that your url
instead looks like

/customers/pragmatic_programmers

where pragmatic_programmers is the name of the customer, downcased and
with underscores added. Your customers might like that even more
since they could bookmark ‘frequent flyers’.

Nested routes are similar. The ‘nesting’ comes in the fact that you’d
get /parent_collection/[parent_token]/child_collection[token]. The
format can be really handy when you’re adding a new item to a child
collection because the identifier is passed along to the controller
that handles the children.

It’s also worth noting that you can completely bypass the RESTful
routing if you want. The routes.rb file permits several ways to add a
url to the route map so you can continue to use the same kinds of urls
that you are using today. In short you give the route a name,
describe it’s pattern (perhaps with a string), and then tell it what
controller and action (method) should respond. The routing system
even permits regex matching, making it easy to provide, for example,
dated blog entries that conform to something like /posts/2008/may.

Yes, it’s somewhat familiar with the ASP.net 3.5 extensions MVC
framework routing.

As a reformed C# guy myself I can say that I never look back and wish
I had the ‘opportunity’ to select just the right collection of objects
and configurations from among the 25K+ that MS has to offer. In fact,
I’m thankful every day that I hooked up my friend to do contract work
on a legacy project so I can stay .net free for yet another day!

When I saw Rails, and started reading more about it, I’ve considering
dropping .net all together. Well, for the web at least. Only the test of
time will tell how fast I apply the same, or adjusted patterns, to rails
and if that makes me save money or waste money.

Feel free to contact me off line if you want to talk any more
specifics.

Could you send me and e-mail and / or MSN to ahkaru [at] gmail [dot] com
? Would be interesting to discuss a couple of points with you.

Best regards and thanks again.