Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Trailblazer: A new architecture for Rails (github.com/apotonick)
138 points by tombenner on Nov 28, 2014 | hide | past | favorite | 50 comments


From the sample chapter:

"Some charismatic leaders in Rails core dislike encapsulation. The Fear Of The Class, the freedom of a dynamically typed programming language and the strong will to make it different to Java and its “over-abstraction” has led a generation of developers to unlearn what object-orientation really is about - and neglect this ingenius concept."

I've had similar thoughts myself. It's almost as if, at this point, the renegade, hip thing to do is to start proudly wearing "enterprisy-ness," like a faded, well-worn MC Hammer t-shirt.


This is purely intentional criticism, you don't need a different framework on top of Rails to practice object oriented development.

Enterprise Java hell lives on for many developers in the world.


Huh, this is interesting. I've been getting more into Meteor[1] lately, and I see a few things here that mirror my experience there:

* Concept-Driven directories (ie: having your model, views, controller, etc. for everything Comment related in the same directory). Meteor still hasn't figured out what directory structure it wants (you could make up your own and things would still work), but I've seen this in several places.

* having an object for each view (I didn't like this about Meteor at first, but it's really just stripping out logic that would have been in the view and putting it somewhere else. It actually makes it a lot easier to debug layout vs. code errors by having the view be as simple as possible)

* I was going to say use of monads, but a) I'm not sure that's what the "call style" and "run style" actually are, and b) Meteor doesn't really use monads, now that I think about it

I'm sure nothing here is unique to meteor either, but it's interesting to read about stuff like this with the added perspective of another framework.

1. https://www.meteor.com/


I've never really understood layer-level grouping. Ideally, the more likely things are going to change together, the closer together you have them.

Given that, it's less likely that you'll change the code for all your models than change the view+controller+model code for a given feature.


That's an ideal scenario, though, that implies that all of your view/controller/model through-lines can be isolated vertically from each other. In fact, controllers often coordinate the actions of multiple models to achieve higher-level objectives, and it's at this point that the relatively greater cohesiveness of layers versus features becomes apparent.


it's useful in practice for denoising file names. unfortunately rails doesn't do this at all, and every controller file is something like `app/controllers/foo_controller.rb`. in Python, if you had a file `app/controllers/foo.py` you'd be able to `from app.controllers import foo`, which is more useful and does an equally good job of declaring the file is a controller without having to write `_controller.rb` every time you do anything with a file.


Or you would just use the class because it's already in the autoload paths. Seeing a lot of opinions from people who don't actually seem to use rails.


au contraire. I have worked on what I suspect is one of the largest Rails apps out there. autoload has been off for a long time (along with many other "convenient" features) for performance reasons.

that's beside the point though, because if you're outside the Rails world you will have to type the whole name of the file if you want to do something with it.


This "architecture" changes so much about Rails that I don't know why it's trying to build on Rails at all. If you don't like the Rails Way, just create another framework.


Because Rails has 10+ years of development on backend tooling that shouldn't be nixed or reinvented on account of a reorganization of files?

Yes, it replaces view rendering completely with Cells, but routing, dispatch, request serialization, activerecord, asset pipeline, rails-provided view helpers and more are all used basically as-is.


The view rendering doesn't need to be done by Rails. I've been using React and Webpack to build the clientside of my Rails apps and have been very happy with that approach. There is nothing that this architecture does that a clientside framework like React cannot do better.


How do you store/version/deploy that, by the way? Do you build your Rails project purely as an API, and a separate project/repo for the React client?


It doesn't make sense to replace Rails views completely in my view. There are parts of the app that are still being served by Rails views because they are not mission critical or have a great solution already in-place. Where React comes handy is when you have an interactive one-page app with a lot of moving parts. I have 2-3 React apps in this current project. Webpack is a great solution for packaging your css, js and other assets in logical units. I think it's much better than Sprockets, but it requires some configuration.


I've played with Weboack for toy projects. Do you have one Webpack project that builds and watches all your React apps, or do you treat each separately? I have a larger project on my todo list, and I'm considering doing a Rails API and a single React app for everything on the client (including URL routing).


Do you use Flux as well? Do you use a router system or still let Rails do most of the routing?


Yeah, I do use Flux, and I love it. I use a mixture of both Rails and a clientside routers, but Rails does most of the work for sure.


I think Nick should be applauded for his attempts over the years to find ways to introduce interesting architectural concepts into the Rails world.


as much as I don't want to quote dhh about anything: http://david.heinemeierhansson.com/2012/rails-is-omakase.htm...

in short, since Rails 3 there is no "Rails Way"


That's just PR.


I like that Trailblazer is promoting some concepts I'd like to see more rails devs use (service objects, form objects), I think this project will be a non-starter for most teams. But after giving the readme a once over and looking at the source code a bit, here are the concerns I would raise:

1. What advantage does this have over using the components it's wrapping? Why not just use the reform or representable gems directly?

2. Things like this introduce a steeper learning curve for newer rails devs, especially when they cause application architecture to deviate so much from what's commonly found in the documentation already available.

3. There seems to be no real documentation on what testing facilities are available for this framework.

That being said, this is not bad at all for a pre 1.0 release. I don't always agree with some of the decisions apotonick (the author) in the code he publishes, but I do respect him for the fact that his work promotes a lot of discussion in the ruby/rails ecosystem.


I've not used trailblazer myself but I've utilised some of the concepts or similar ones on existing projects and green field projects.

I think the answer to 1. would be hard to express without getting deep into a specific complex application and most people don't want to open source their business applications, especially not as an example of bad code. It would be awesome if someone refactored a typical problematic large Rails app in the open using these concepts. But it's a lot of work/risk just for the greater good.

2. I'd suggest that the newer devs are going to find it easier navigating a clean codebase (with architectural complexity) than a well established Rails app with a lot of the code smells and complexity that come with going The Rails Way.


Yeah boy, that's the spirit! Everything is an object! As in... ummm, kingdom of nouns, yeah that one.


What advantage is there to form objects?


The documentation would benefit from some clear examples of how the new architecture provides benefits over the existing ones. The given examples are opaque and its superiority is merely asserted, with references to concepts such as "cells" which are not defined.


the sample chapter of the book is more detailed: https://leanpub.com/trailblazer


As some have previously stated, this probably shouldn't be on rails... It seems like it should be built on top of a lighter framework, like Sinatra.

Also, it looks like concepts === components. There is a lot to learn from meteor's approach to this -- While I haven't mastered meteor (still very much learning it), it's the most component-ized framework I've seen (and it's extremely unique), and their approach is good/consistent.


Trailblazer looks interesting, and there are a lot of good ideas in here. One issue I have with it after reading the documentation is that the code is organized around "Concepts" and at the core of each Concept appears to be a single Model. All of the Form, Presenter, and other Operation objects live within a Model's namespace where often the @model is implicit. This works well if your business logic only applies to CRUD operations on individual Models, but in reality that is rarely the case.

I tend to use a service object abstraction based around concerns, or "business stories". My service objects map to specific scenarios or pieces of business logic that often utilize multiple underlying Models and/or other entities (eg. third party interactions services).

It wasn't clear to me whether such a scenario is discouraged with Trailblazer, or maybe not even possible.


You can definitely compose operations, and have an operation that deals with multiple database models. The sample chapter from his book goes into a little bit of detail about it near the end, but TLDR you use a Twin object that has a reference to both of your dbmodels for defining (or delegating) validation and form building.


I'm intrigued, and would love to hear of anyone's experience using this, particularly in a production environment. One question: does it have performance implications, one way or another?


JSON rendering performance is a major concern for most of my Rails apps, and I'm wondering the same thing. I've not used Roar (https://github.com/apotonick/roar) before which is what Trailblazer uses for JSON serialization/deserialization. It seems to be full-featured, but I'm interested to hear how it performs compared to other gems. I currently use OJ + Jbuilder + a ton of fragment caching and it's not great but better than anything else I could find.


> JSON rendering performance is a major concern for most of my Rails apps

I've always wondered why this is the case. Faster JSON libraries don't seem to help. Similar frameworks don't have this problem. It just seems the Rails serialization code is slow in and of itself, it's not what it calls out to. Maybe there's a contention issue somewhere?


There have been some historical issues that should have been sorted out in more recent releases. The TL;DR is that Rails wouldn't actually use your faster gems, even if you thought it was. See https://github.com/rails/rails/pull/12183 for the work that was done to improve this. There was another issue too that detailed the specific problem, but I can't find it right now.


I haven't used it, but read up on it after starting to use the Reform gem. It seems more geared toward forcing cleaner, more encapsulated code, which should make your rails app more maintainable in the long run. I don't think that there's any major functional changes that would impact performance.


How is this not called Railblazer?


Misread as Tribalizer initially myself, was wondering why a name so strange...


Architecture Astronaut


Say that again after you have to learn a rails app with 1500 line models built "the rails way." Controller -> model breaks down when you reach a certain size.

Or worse, giant controllers and models with no clear distinction.


You can go a long way with using simple Ruby objects to break up logic and separate out logic from models. If developers are writing 1500 line models and the lead developer isn't doing anything about it a adding new abstract concepts isn't going to help.


the author argues based on his experience refactoring legacy Rails apps that these problems are so common that they must stem in some way from the framework. I'm not sure how true this is, but my experience is that Rails doesn't give you a lot of help in defining where this extra logic should go. There are a lot of blogs and the like with differing suggestions about how to structure your Rails app, suggesting that this is a real problem and that there is no real consensus on how to fix them. Personally I'm happy to see a framework which builds on the best features of Rails while also trying to offer some solutions for applications that have outgrown the simple MVC structure.


I really cant agree with this enough.

A very common example of model bloat I see is authorization logic, and libraries like Pundit do an excellent job providing a simple framework for extracting such logic into their own ruby classes.


In a way a lot of parts in Trailblazer are just that: "simple Ruby objects to break up logic and separate out logic". Not just from models but in the views, controllers and other places too.

Lots of Rails devs go through a process like the following:

* I want to introduce a Subscription, but that is not something stored in the database, rather it creates an Order, Invoice, Account and assigns products to them. Let me create a simple PORO for that.

* Now, where to stick that? Models? For now, that will do.

* I want to introduce a Trial, which is rougly similar to the Subscription just with different parameters.

* I want to introduce an Upgrade, wich can turn a Trial into a Subscription.

... and so on.

Quickly turning your "simple Ruby objects" into an even larger mess then the mess they try to solve. So you'll be adding abastractions, giving them names and common places in your app. And there: you've just built a part of a framework like Trailblazer.


Yeah, and I don't think anemic models are the way to go. That's swinging back the other way too hard. Rails could do with promoting a service/app layer if anything new were to be introduced. A healthy dose of DDD concepts.


I thought the original promise of rails was that you could use traditional OO concepts to combat complexity.

Rails doesn't tell you to stuff all your logic into models.


I think the issue is monorails (monolithic rails apps). If you have a single domain object you're representing that's that complex, you'd done a poor issue of modeling your domain. It doesn't matter if you write the logic in the model or controller, at that point you're just pushing code around -- you need better abstractions.


"Trailblazer is a thin layer on top of Rails. It gently enforces encapsulation, an intuitive code structure and gives you an object-oriented architecture."

Rails already has all three of these things...trying to put another layer on top only makes things more complicated...


You have my compliments and respect for undertaking an endeavor like re-thinking (and actually implementing!) rails architecture, so my apologies if my comments sound harsh or cynical. (I just want to talk about it)

I'm having a hard time understanding the need for this, especially because I'm highly suspicious of building any significant amount of abstraction on top of rails. This is because rails core is fucking insane. Besides the fact that it's in a constant state of flux, the amount of dynamic/meta/runtime fuckery that takes place makes it a living nightmare for security (and performance).

Rails already provides a highly-specific set of "convention over configuration" settings that work for most users with a basic understanding of HTTP. How exactly does this framework make those settings "better" besides re-arranging the basic set of abstractions that base rails provides (and adding more "fuckery" on top of that)?

Who is your target user group? Rails already attracts a significant number of new developers who have never worked with the web before because the abstractions are relatively easy and straightforward to understand. This is what makes rails very impressive and attractive, but, at the same time it locks a whole generation of new web developers into "the rails way" of thinking about the web (and later have to be untaught when they realize performance is actually important).

IMO If a "better" ruby web framework was to come into existence, I would encourage it to be more in touch with the basic abstractions that are already built into HTTP (see https://www.ietf.org/rfc/rfc2616.txt) and not try to over-abstract those basic concepts so that moving among http frameworks (in ruby or other) requires significant domain knowledge.

Are there any performance benchmarks? I could see a project like this unintentionally adding 2-3x performance hits (without realizing it) due to the extra abstractions.

BTW, what the fuck is up with this book? I assume you want to sell it to me in the future so that I can learn how to "properly" use your brand new open-source framework? What the fuck is wrong with a readme and a wiki, especially if you ever considered larger open-source adoption? Are you so self-righteous that you think I should feel entitled to have the pleasure of being able to download "a preview" of your e-book in your fucking readme?


Don't be an asshole man, the guy made a framework, the readme is plenty fine, and he has a nice book to sell with it. How are you so self-righteous to judge how other people should run their open source software project? How do you feel so entitled that you should get everything this guy makes for free? He is just asking for you to consider buying the book he spent a lot of effort into writing.

BTW, what's up with the crazy assumptions about performance hits? You do realize we're talking about Rails here right?


Sorry...just been annoyed at rails lately, was drunk reading through here, and wrongly took out my personal frustrations as a diatribe against the author. I'm an asshole.


Thanks for setting it right :)


", so my apologies if my comments sound harsh or cynical."

While in fact you don't mean them to _just_ be harsh or cynical, but you also want to personally insult the OP and make him feel bad about posting something.

'Apology declined' I would think.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: