Sequel::ModelでJoinしたテーブルの値をWhere条件にするやりかたとか
泥縄で調べた事なので、このやり方で本当に良いのかわからないけどとりあえずメモ。
先日公開した、http://nbc.skr.jp/なんですが、ModelにSequelを使用しました。で、生放送とコミュニティのデータ管理するためにこんな感じのコードを書いた。
require 'rubygems' require 'sequel' Sequel::Model.plugin(:schema) DB = Sequel.sqlite('kaitemita.sqlite3') class Live < Sequel::Model unless table_exists? set_schema do primary_key :id text :live_id #生放送ID text :name #番組名 date :pub_date #放送開始時間 text :description #番組説明 text :community_id #放送コミュニティ end create_table end many_to_one :community, :key => :community_id, :primary_key => :community_id end class Community < Sequel::Model unless table_exists? set_schema do primary_key :id text :community_id #コミュニティID text :name #コミュニティ名 end create_table end one_to_many :lives, :key => :community_id, :primary_key => :community_id end
livesとcommunitiesにアクセスするためのLiveとCommunityクラスです。
で、両クラスを使用するこんな感じのプログラムを書くと、最近放送を開始した順番に10件ほど放送の情報を表示してくれる、と。(もちろんDBにデータが入って無いと駄目だけど)
live = Live. order(:pub_date.desc). limit(10) puts live.sql live.all.each do |l| puts "#{l.live_id} (#{l.pub_date}開始):#{l.name} (#{l.community.name})" end
そのまま表示するのも芸がないので、番組名に「絵」という文字が含まれているものだけを抜き出そうとするとfilterメソッドlike使ってこんな感じ。
live = Live. filter(:name.like('%絵%')). order(:pub_date.desc). limit(10) puts live.sql live.all.each do |l| puts "#{l.live_id} (#{l.pub_date}開始):#{l.name} (#{l.community.name})" end
同じ事をcommunitiesテーブルに格納されているコミュニティ名でやろうとした場合、単純に:nameをcommunity_name置き換えただけではそんなフィールド無いってエラーになります。
で、ネット上にあるSequelのサンプルを見るとJoinメソッドを使用してテーブルを連結している例があるのでそれに習ってやってみると一応動きました。
live = Live. join(:communities, :community_id => :community_id). filter(:communities__name.like('%絵%')). order(:pub_date.desc). limit(10) puts live.sql live.all.each do |l| puts "#{l.live_id} (#{l.pub_date}開始):#{l.name} (#{l.community.name})" end
でも、これだとせっかくModelクラスに関係とか定義してるのに使われないし、定義があちこちに有るとか、方やテーブル方やクラスというのはなんか嫌なのでどうにかできないかなーとあれこれ調べたところ、eager_graphというメソッドがありました。
live = Live. eager_graph(:community). filter(:community__name.like('%絵%')). order(:pub_date.desc). limit(10) puts live.sql live.all.each do |l| puts "#{l.live_id} (#{l.pub_date}開始):#{l.name} (#{l.community.name})" end
一応、Liveクラスのmany_to_oneを使用してSQLを作成してくれる模様。これでいいのかなぁ。