ActiveRecord interface to Arel is awkward, requires find_by_sql(query.to_sql)

Sorry, but I have no idea what you're talking about. Could you

please give me an example of one of those AR plugins you’re referring to?

Sorry, you are right i was referring to gems that involve querying the database through AR, Devise to say one that yourself mentioned.

As in a past thread in which we discussed together, in brief my thought is: there are probably some good reasons that prevent rails to drop ActiveRecord, but with a well thought and well designed interface the fact that ActiveRecord is the default for rails would not seal the giant support AR has to the other ORMs or persistence solutions.

The situation with Sequel is probably similar to what i faced once with mongoid. At first glance all seemed good to me, but then i realized i was spending a lot of time on the framework (patching something, choosing alternative gems working with mongoid …) more that on my business (and I probably liked this as i 'm writing here now :wink: )

I think that this is a case in which a bit more of engineering would not hurt.

Maurizio

I guess I got what you mean, although I don’t agree.

Rails 3 is a pretty solid and modular framework in my opinion,

lacking just a decent documentation.

It doesn't rely on AR for anything. It is just included by default

but if you run “rails new app -O” then AR won’t be included as a dependency (although installing rails will also install AR, which seems wrong to me as AR shouldn’t be a dependency for Rails).

But you can't just define a common API that all gems will be able to

use regardless of which ORM solution you chose. The ORMs can take very different approaches when dealing with API design and that is what make them so interesting.

The problem relies in the gems in my opinion. They should follow the

SRP instead of just assuming things to get a broader range of users. Even if there are any interface “keyword” in Ruby, you can still write interfaces in a number of ways.

The easiest one would be to document what methods you expect from

the ORM for it to work and how they should respond.

An even better approach would be to provide a test-suite that all

conforming adapters would pass when correctly implemented.

But if Devise had it only documented I wouldn't need to investigate

the source to understand what to add to Sequel models.

For example, FactoryGirl had it documented that "save!" was the sole

dependency and documented how it works, so it only took one minute for implementing it and getting it to work with Sequel.

DatabaseCleaner was supposed to support Sequel but it seems no one

was using it with Sequel as it was broken and was just fixed recently:

https://github.com/bmabey/database_cleaner/pull/120

RSpec had also good documentation, although no example or built-in

support for Sequel, but there were already lots of examples on how to set-up transactional examples with Sequel with some quick search in the web.

I've only took a considerable amount of time to be able to do an

unsupported usage of transactions with Sequel. Sequel doesn’t provide methods like DB.start_transaction and DB.stop_transaction. You need to use it like:

DB.transaction do

  ...

end

This works with RSpec around(:each):

around(:each) do |example|

    DB.transaction do

        example.run

    end

end

But RSpec doesn't provide an around(:all), so I had to call some

private methods on DB for getting transactions and save points to work in before(:all) and after(:all). The same technique was used for adding support for a sandbox environment.

Knowing which private methods to call and in which order took some

time and a lot of help from Jeremy Evans.

But the way I see, replace AR with Sequel should be much easier than

replacing it by some non relational database solution, like MongoDB. They have completely different approaches and you shouldn’t expect for lots of gems that aim in adding some kind of support for relational databases to be easily integrated to MongoDB as well.

So, this time I think Rails is currently very well designed and I'd

like to thank a lot Yehuda, José Valim, Piotr Sarnacki and all core developers for the excelent job they did on making Rails more modular and easy to extend with Engines. A lot of unnecessary dependency was cut off and Rails just doesn’t seem to be the issue anymore for adopting alternative solutions like testing framework, orm and JavaScript library. This was really a great engineering design and the Rails community should be proud of their code base.

Educating gem authors to follow Rails' example should be much easier

and less painful.

Cheers,

Rodrigo.
        Sorry, but I have no idea what you're talking about. Could

you please give me an example of one of those AR plugins you’re referring to?

      Sorry, you are right i was referring to gems that involve

querying the database through AR, Devise to say one that yourself mentioned.

      As in a past thread in which we discussed together, in

brief my thought is: there are probably some good reasons that prevent rails to drop ActiveRecord, but with a well thought and well designed interface the fact that ActiveRecord is the default for rails would not seal the giant support AR has to the other ORMs or persistence solutions.

      The situation with Sequel is probably similar to what i

faced once with mongoid. At first glance all seemed good to me, but then i realized i was spending a lot of time on the framework (patching something, choosing alternative gems working with mongoid …) more that on my business (and I probably liked this as i 'm writing here now :wink: )

      I think that this is a case in which a bit more of

engineering would not hurt.

I guess I got what you mean, although I don't agree.
Rails 3 is a pretty solid and modular framework in my opinion,

lacking just a decent documentation.

Yes it is, but this does not mean it is perfect. The limits of Rails design are more evident on the long run, when you start dealing with changes and expecially with unexpected ones. Also they are not a problem in general, but only for certain applications, and some of them fall in the use cases of rails framework.

It doesn't rely on AR for anything. It is just included by default

but if you run “rails new app -O” then AR won’t be included as a dependency (although installing rails will also install AR, which seems wrong to me as AR shouldn’t be a dependency for Rails).

Of course rails does not rely on AR but it is the default, and so it has the major support from the community.

But you can't just define a common API that all gems will be able to

use regardless of which ORM solution you chose. The ORMs can take very different approaches when dealing with API design and that is what make them so interesting.

I don’t want a generic api for all ORMs but i wish that the default (AR) has a better and more generic API so that we can drop / integrate it without drop the support from community gems.

The problem relies in the gems in my opinion. They should follow the

SRP instead of just assuming things to get a broader range of users.

You are right, but you can say now that all the gem creators take this into account?

Even if there are any interface "keyword" in Ruby, you can still

write interfaces in a number of ways.

You are right again, i’m not saying that the missing of an interface keyword is a problem by itself but i’m concerned to the fact that due to this many times ruby libraries expose the implementation to the client code (eg. we need to call #arel_table). Also and probably more often, libraries API will change when implementation changes.

The easiest one would be to document what methods you expect from

the ORM for it to work and how they should respond.

An even better approach would be to provide a test-suite that all

conforming adapters would pass when correctly implemented.

Documentation is probably enough to express interfaces but would probably be better to enforce the separation between interface (what does not change) and implementation (what can safely change) by delegating to a void implementation in the top level layer, and then injecting the real implementation into the stubbed one.

This way we would be sure that the top level interface will stay independent from the concrete implementation code (as an example think of AREL case again).

So, this time I think Rails is currently very well designed and I'd

like to thank a lot Yehuda, José Valim, Piotr Sarnacki and all core developers for the excelent job they did on making Rails more modular and easy to extend with Engines. A lot of unnecessary dependency was cut off and Rails just doesn’t seem to be the issue anymore for adopting alternative solutions like testing framework, orm and JavaScript library. This was really a great engineering design and the Rails community should be proud of their code base.

Educating gem authors to follow Rails' example should be much easier

and less painful.

Well here i see a misunderstanding i don’t think that Rails has a bad design but that it can move to an approach that is a bit more friendly to enterprise applications where it doesn’t make things too complicated in order to make our applications more maintainable and age resistant.

Probably i need to cite someone that is better than me: http://www.languageparallax.com/wordpress/?p=39

I had the feeling that a more enterprise-oriented approach can be achieved in rails when i looked at play framework, (even if the current version is a nearly unusable mess due to its young age) it proves that there are ways to fill the gap between enterprise requirements and simplicity and quickness belonging to agile frameworks like rails.

I’know that you don’t like it but sometimes i prefer data mapper and domain driven design over active record and database driven design, the same way i would like to see a two-step view approach for views.

If for the latter there are no problems (i can quickly implement it with a few lines of code and only my views will depend on it) for the first one i’ve a lot of trouble due to the lack of solid support, since i don’t think that rails will drop AR my proposal is to have at least a complete querying/mapping interface that can bridge the gap from ORMs.

In any case i will look at Sequel, now i’m too curious! :wink:

Maurizio

      ...
        Em 05-06-2012 00:17,

Maurizio Casimirri escreveu:The problem relies in the gems in my opinion. They should follow the SRP instead of just assuming things to get a broader range of users.

      You are right, but you can say now that all the gem

creators take this into account?

That is just how open-source and community-driven development work

:slight_smile:

        Even if there are any

interface “keyword” in Ruby, you can still write interfaces in a number of ways.

      You are right again, i'm not saying that the missing of an

interface keyword is a problem by itself but i’m concerned to the fact that due to this many times ruby libraries expose the implementation to the client code (eg. we need to call #arel_table).

If you just need the table name, you can just use

YourModel.tablename I guess:

http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name

Man, it was really hard to get this specific link from the API. I

needed to show the frame source in Chrome and then extract the “source:” prefix… Having an API based on frames already sucks, but not being able to right or midle-click the link in the left panel makes it even worse.

      Also and probably more often, libraries API will change

when implementation changes.

Having an interface does not provide any guarantees per se. I

maintain a Grails application and their API has changed in a minor upgrade (2.0.1 → 2.0.2) despite Groovy and Java providing “interface” as a keyword. Having a void implementation won’t help here. If you don’t want something to change in the Rails community that usually means writing a test for it.

        So, this time I think

Rails is currently very well designed and I’d like to thank a lot Yehuda, José Valim, Piotr Sarnacki and all core developers for the excelent job they did on making Rails more modular and easy to extend with Engines. A lot of unnecessary dependency was cut off and Rails just doesn’t seem to be the issue anymore for adopting alternative solutions like testing framework, orm and JavaScript library. This was really a great engineering design and the Rails community should be proud of their code base.

        Educating gem authors to follow Rails' example should be

much easier and less painful.

      Well here i see a misunderstanding i don't think that Rails

has a bad design but that it can move to an approach that is a bit more friendly to enterprise applications where it doesn’t make things too complicated in order to make our applications more maintainable and age resistant.

Well, this argument often pops out in the Rails community. I won't

repeat myself on my own opinions:

http://rosenfeld.herokuapp.com/en/articles/ruby-rails/2012-03-04-should-we-move-forward-or-remain-backward-compatible https://groups.google.com/forum/#!topic/rubyonrails-core/fTvmRxtFGcE/discussion

Probably i need to cite someone that is better than me: http://www.languageparallax.com/wordpress/?p=39

      I had the feeling that a more enterprise-oriented approach

can be achieved in rails when i looked at play framework, (even if the current version is a nearly unusable mess due to its young age) it proves that there are ways to fill the gap between enterprise requirements and simplicity and quickness belonging to agile frameworks like rails.

Yes, this is possible, but I don't want that in Rails. That is

because if you want to keep backward-compatibility at all costs you’ll end up with a code base that is hard to maintain and inconsistent and will prevent you from moving forward sometimes.

For example, I don't make any effort for making my own gems

compatible with Ruby 1.8 because I simply don’t like to write hashes like {:symbol => value}, preferring {symbol: value} much more. When you have to remain backward-compatible to Ruby 1.8 support, it means more code to maintain which can be really a pain.

This is valid for most other backward compatible decisions.
      I'know that you don't like it but sometimes i prefer data

mapper and domain driven design over active record and database driven design, the same way i would like to see a two-step view approach for views.

All of them are valid engineering decisions and I don't believe

there is a right way of doing things. I like to say that Rails is just Ruby. It is a glue that will help you start coding your applications helping you with decisions you don’t care about, like what database or ORM or template engine or test framework or JavaScript framework you should work. If you don’t care about them, let Rails choose a default one for you. If you do care, then change the defaults. For example, I opted for jQuery when Prototype was the default. I opt for RSpec for testing as well as Sequel for ORM. And opting for other tools in Rails is damn simple nowadays.

There is no reason why someone should really try to keep with Rails

defaults nowadays IMO. You should keep thinking on your app as an application like you would do in Java or any other language/framework. Rails will just help taking some unimportant decisions for you by default unless you care about them.

So, if DataMapper makes more sense for you, I'd go for it if I were

you. The same for your views although I have no idea what two-step views mean. Personally I use a SimpleDelegator class as a presenter for my JSON representations, for example if that is what you mean…

      If for the latter there are no problems (i can quickly

implement it with a few lines of code and only my views will depend on it) for the first one i’ve a lot of trouble due to the lack of solid support, since i don’t think that rails will drop AR my proposal is to have at least a complete querying/mapping interface that can bridge the gap from ORMs.

The lack of a well defined and documented API is a blocker issue for

me and probably the main reason I stopped using it. So, I heartedly agree with you on that one. Also, any internal implementation detail should be hidden from the API documentation.

In any case i will look at Sequel, now i’m too curious! :wink:

Let me know (outside this list) if you have any questions about it.

Cheers,

Rodrigo.