Live data from Hacker News

Where the logic hides in rails apps

gammons.github.com

41–50 of 56 posts

Re: Where the logic hides in rails apps

#41

While I don't like the name of the service object "CreatesContact", I disagree with the statement that the sending of an email should reside within the create_contact! method. The author's intent is to shield any new developers from methods that say one thing and do another, yet he adds email delivery into the create_contact! method without informing the developer what may happen (unless some magic flag is set somewh…

Yeah "CreatesContract" is a weird name. ContractCreator, or ContractRepository (so it can do more than just create objects) makes more sense to me.

Plus he should probably just break the send_email method into it's own method, which he can then call depending on if create_contact returns successfully.

Re: Where the logic hides in rails apps

#42
post #6

Maybe this is naive, but what's wrong with just putting `UserMailer.welcome_email(user).deliver` in the controller, right after the user is created? In my mind, delegating an email to be sent should be a job for the controller. IIRC, the Rails ideology says that "Models should not know about any part of the application except for their own datastore." Even though the :after_create hook is the "Rails way", doesn't thi…

I like it too, and have this line of code in a few apps. It's not technically right because, in MVC, your business logic belongs in your models. Imagine a situation where you want to bulk-create Users via script (or, simply, not via your controller "create" action). Shouldn't those bulk-created users get emails too? It depends on your business logic, hence, your model.

Well, the business logic that the given model is responsible for belongs in the model. For instance, calculating an order total belongs in the Order model if you are building a shopping cart. However, you shouldn't break separation of concerns just to keep 100% of the business logic inside your object models.

Having tightly coupled objects that depend on other classes in your application that you wouldn't expect is worse than having a little bit of business logic in your controller (or some service object), in my opinion.

Re: Where the logic hides in rails apps

#43
post #37

Disappointed not to see some comments from Django/Python folks here. Or node, mvc.net, Cake, CodeIgnitor etc etc. Is every language/framework community doomed to repeat these debates in isolation ad infinitum?

I commented in here a couple times and I do ASP.NET MVC development in C#. It just seemed like the concepts are so similar that whether you write it in C# or Ruby doesn't particularly matter.

Re: Where the logic hides in rails apps

#44
Ok, I've been working on an architecture pattern that is very similar to this idea and it's basically inspired by Uncle Bob's Clean Architecture and Screaming Architecture posts. I call it the Obvious Architecture.

What the OP writes about is a good first step and frankly, is very close to right, but why stop there? Why not ditch ActiveRecord models all together and totally decouple persistance from the "app"? Honestly, the coupling of your models and logic to a database is really where most of this trouble starts.

In the Obvious architecture the app is separate from the delivery mechanism (rails/sinatra/whatever) and also from the external persistance mechanisms like databases, queues, caching, and so on. You can mix and match both delivery mechanism and persistance methods. So, you could write a CLI app against the filesystem and then make a rails web app with a mysql persistance mechanism without changing your "app" at all.

The whole thing is built from day one to be TDD and in a recent app I wrote, it has some 78 rspec tests that run in 0.03 seconds.

I'm in the process of documenting and open sourcing the whole thing. There is a project generator gem available now called 'obvious' and you can read more at http://obvious.retromocha.com/

When I have better documentation and examples available, I plan on posting to HN, but all questions are welcome.

Re: Where the logic hides in rails apps

#45
No, really, just use modules - they are testable and reusable and any truly professional Rails dev is going to have zero problems understanding and working with them. This smells of someone very new to Ruby/Rails.

Re: Where the logic hides in rails apps

#46

We have been moving the complex logic out of the models into libraries. But we are not happy with this approach. We also find it difficult to cleanly develop views where data is needed from several different models. The whole Rails REST and MVC model gets in the way. Would love to hear about how other wiser people have deal with these situations.

I think what you are in need is nothing to do with model separation. But, you need to be careful about which code belongs to your business logic. For the views you mentioned, I don't know your code but I think you may use something interim, like a presenter code which takes data from the models and helps views to show it.

so use presenters... easy.

Re: Where the logic hides in rails apps

#47

While I don't like the name of the service object "CreatesContact", I disagree with the statement that the sending of an email should reside within the create_contact! method. The author's intent is to shield any new developers from methods that say one thing and do another, yet he adds email delivery into the create_contact! method without informing the developer what may happen (unless some magic flag is set somewh…

why not use an observer to send the emails?

Re: Where the logic hides in rails apps

#48

We have been moving the complex logic out of the models into libraries. But we are not happy with this approach. We also find it difficult to cleanly develop views where data is needed from several different models. The whole Rails REST and MVC model gets in the way. Would love to hear about how other wiser people have deal with these situations.

The last time I was on a project where we found ourselves facing that problem, we solved it by going to a Javascript-based thick client (aka, a Single Page App). The server's responsibility was to do nothing but supply a JSON API to the thick client written in Javascript.

It solved the problem nicely -- in fact, so much so that it uncovers the fact that there's a flaw in the concept of using MVC to build a server-driven web app. (Not an insurmountable flaw, obviously, because we've all done it for years. Maybe I should call it an "awkwardness" or something like an "impedance mismatch").

Re: Where the logic hides in rails apps

#49
Learn your tools. New developers will need to do the same. There's zero substitute for experience. Rails solves the most common problems easily.

It's extremely common to do things upon saving. Once you need to do more than one thing upon saving you then move to a more "event" based approach.

Rails was mystifying when I first picked it up, and parts of it are mystifying today. But something as trivial as the callback chain will be second nature after some time and several apps later.

Re: Where the logic hides in rails apps

#50
If you have a use case that doesn't fit into your basic CRUD why not just create a new REST resource for it? For instance in my current app we have an InstallsController. This creates a new installation of the plugin, updates the user's account and send out an email. I've always steered clear of model callbacks as they don't play well with FactoryGirl/Machinist etc. As such the controller's create action describes everything that happens when our plugin is installed(it's still only 4 lines long).

This strategy of using new REST resources combined with modules for models where appropriate seems a very comfortable way to structure a large application. It fits into the rails conventions well and doesn't require new developers to do anything they're not familiar with. The other nice advantage is that your routes configuration gives a great overview of everything that can happen in your app.

Post reply on HN