Saturday, March 19, 2011

Серенькие будни Sequel

Если не смотреть на sql, который генерируют ORM, можно чувствовать себя хорошо. Если посмотреть на sql, который генерирует ORM, можно почувствовать себя очень хорошо, из-за того что не нужно получаемый sql ни набирать руками ни не дай б-г читать глазами.

Положим, у нас есть 2 отношения [1]: articles и tags. Обе модели которых, связанны как many-to-many. Отношения самые примитивные:

create_table(:articles) do
  primary_key :id
  String :title, null: false
  DateTime :updated, null: false
end

create_table(:tags) do
  primary_key :id
  String :name, null: false
end

create_table(:articles_tags) do
  primary_key :id
  foreign_key :tag_id, :tags
  foreign_key :article_id, :articles
end

Задачка: поискать в tags.name строчечьку foo и вывести связанные articles в обратном порядке. Для Sequel это выглядит так:

Article.order(:updated.desc).
  filter(id: DB[:articles_tags].select(:article_id).
   join(:tags, id: :tag_id).
   filter(:tags__name.like('%foo%'))).each {|i|
  puts i.title
}

Любой согласится--это гораздо читабельнее sql! Ну, ok, согласится, когда ему покажут отот sql:

#<Sequel::SQLite::Dataset: "SELECT * FROM `articles` WHERE (`id` IN
(SELECT `article_id` FROM `articles_tags` INNER JOIN `tags` ON
(`tags`.`id` = `articles_tags`.`tag_id`) WHERE (`tags`.`name` LIKE
'%mike%'))) ORDER BY `updated` DESC">

jfc.

[1]Если иногда вставлять это реликтовое слово в разговор посреди ланча, то после n-го по счету выговаривания вами отношения, добродушный собеседник начнет есть в (n-1)/3 раз медленнее.