Rails 3.1 and the lack of a service layer - ruby-on-rails-3.1

I'm writing an hotel-like app in Rails 3.1 and I'm new to Rails.
I'd need some advice about how write what is normally managed in the service layer of an app.
The app needs some service to calculate the price, and this methods have to be available for more than one controller. Till now I put all this stuff in a controller but now I have to get it out from there and really I' don't know how and where.
I thought about writing a helper and include it in the controller but I dislike this solution because helpers should only help to render stuff in the view and they shouldn't mess with the business layer related tasks.
How would you code this?

Maybe you can create a folder named services
/app
/controllers
/services
calculation_service.rb
Then you use it on your controllers like this:
def show
#model = Model.find(params[:id])
#total = CalculationService.calculate_sum(#model.price, #model.subtotal)
end

I wouldn't even do this in the controller. I would push the logic to your model if possible. If it's required in multiple models, I'd create a mixin in your lib folder and include it in each model.

Related

Laravel Routes - is it possible to not use them at all?

I'm a Laravel 3.x beginner with a CI background.
I'm very acquainted to use controllers rather than routes and I'm having issues trying to use controllers in Laravel.
For example: let's say I have the home_controller and the "about" action. My problem is that I'm only able to access the "about" action by setting a route that points to it - something I think is undesirable.
Is there a way to get the "about" action to work without setting a route?
In laravel, everything can be accomplished using either Routes and/or controllers.
However, using both routes AND controllers is suggested for great flexibility. See this article for more informations and some examples of how to combine routes with controllers.
Anyway, if you want to use controllers (which is perfectly acceptable), you need to register them in your routes.php with Route::controller('yourcontroller') before you can use them.
Everything has to be routed in Laravel. But, you don't have to manually route each method. You could do something along the lines of Route::controller('admin').
See here: http://laravel.com/docs/routing#controller-routing
I like Mike Anthony solution. When you're using only controllers this detect method is everything you have to do - this will register automatically all of your controllers. Best hand free solution so far.
The usual controller registration is, as the guys already mentioned, this:
Route::controller('controllername');
You have to register all controllers like in the example above. It is one line of code per a controller, and it is the rule.
But if you have a static page or a login action (page), a good practice is to create a Route controller (anonymus function), not a classic controller (in controllers folder).

In MVC3, how do I override the TempDataProvider globally?

I'd like to change the TempDataProvider in an ASP.NET MVC3 application... I know I can do this on each controller by overriding CreateTempDataProvider... but I was wondering if there is a way to do this in 1 spot ("Global.asax?") for all controllers.
My reason is that my site is on a cloud server... and I want to implement the Post-Redirect-Get pattern in some cases, but I don't want the user to be sent to another server and never get his message.
It seems you could write your own ControllerFactory. Here you could then, after retrieving the controller from the base DefaultControllerFactory class, set the TempDataProvider to your implementation. See more details here.
This probably does what you need, but personally I would prefer more then next approach:
I find it a good practice to have all your controllers inherit from some 'base' controller class. Common controller logic (like overriding CreateTempDataProvider can then be done in 1 place.

Rails structure, should I use a service layer in this case?

I'm new to Ruby and Rails and I'm making my first app. Basically I'm parsing HTML and sending it as JSON to the client.
Right now I've two sources for the HTML data but I could have more in the future. Because of this I thought that it'd be a good idea to remove the code responsible to parse the HTML from the controller and put it into a service layer. I came up with this structure:
app
controllers
main_controller.rb
model
project.rb
task.rb
services
source1_service.rb
source2_service.rb
The MainController call both services to get the projects and tasks; each service parse its own HTML.
Is this a good solution? Is there a more RoR way to do this?
put your services in your models directory, there is no rule that all models have to extend from ActiveRecord::Base, but your services are opaquely data models to the rest of your app (if I understand you right). Ideally, let the service code mimic active record so other people that are just using your model code dont have to know its a different than any other model in your rails app.
Unlike in the Java world, 'the service layer classes' concept is not really popular/used in the RoR world. Its a good idea to remove that code form your controllers (you want your controllers to be thin). But i think you can inject them to your models. If you feel its getting too complicated you can break up your extra code into modules and mixin those modules to your models.
Its not the one and only way of doing things though.
However if parsing HTML include some common logic that can be reused, even in another project its a good idea to put it inside the lib/ folder.

How to implement projects in Backbone.js TODOS-app?

Hey! I'm trying out Backbone.js and have followed the annotated source of the TODO's app.
I fail (don't know how this should be done) when trying to implement projects, which has tasks as "children". So that i can change project and view different lists of tasks.
How should i do this? Some tips for beginner tutorials would also be great :)
The backbone docs mention a pattern for doing something like this:
http://documentcloud.github.com/backbone/#FAQ-nested
So, I would create a new model called a project that has a property called 'tasks' which is an instance of a TodoList collection.
I can't speak to storing the data, as I've never looked at the localStorage used in the TODO app.

KohanaPHP Controller. Should I group them?

I'm new to OOPHP and frameworks at all.
I'm just wondering...
I have few controllers:
dashboard
signup
login and few more
I've put them into users directory. Everything is working correctly, I'm just wondering if I should put everything in one controller and signup, etc. should be a method of users controller? Or am I doing it correct way?
Regards,
M
It's totally up to you. The stuff you currently have could probably all go into one controller (user controller in this case), but it can build up to request the separation you already have, e.g. separate controller for each action, grouped by a prefix.
Good thing about kohana is that it allows you to do stuff like this the way you want to, there isn't a single guideline about putting many 'common' actions into the same controller; do it as you like / find appropriate.

Resources