render_to_string の罠
rails 4.1.4
render_to_string(:index, layout: false) # => "文字列"
コンソールでの評価結果やメソッドの名前からは String が返ってくるように見える
でも実際は ActiveSupport::SafeBuffer が返ってくる
render_to_string(:index, layout: false).class # => ActiveSupport::SafeBuffer
さらに to_s で String にならない
render_to_string(:index, layout: false).to_s.class # => ActiveSupport::SafeBuffer
String を得るにはこうする必要があった
render_to_string(:index, layout: false).to_str
ツイートの内容を View に書いておいて Rubytter でツイートしようとしてハマった
text = render_to_string(:index, layout: false) rubytter.update(text) # NoMethodError: undefined method `each_byte' for nil:NilClass # from /usr/local/rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/uri/common.rb:307:in `block in escape'
各国リーグの昇降格制度
把握していないところがあったのでまとめました。
2014年現在の制度です。
イングランド
プレミアリーグの下位3クラブがチャンピオンシップに自動降格。チャンピオンシップの上位2クラブが自動昇格。
チャンピオンシップの3位から6位までのクラブでプレイオフを行う。プレイオフは3位と6位、4位と5位でホームアンドアウェー形式で戦い、その勝者が一発勝負の昇格決定戦へ。
ドイツ
ブンデスリーガの下位2クラブがツヴァイテリーガに自動降格。ツヴァイテリーガの上位2クラブがブンデスリーガに自動昇格。
ブンデスリーガ16位とツヴァイテリーガ3位のクラブは入れ替え戦へ。入れ替え戦はホームアンドアウェー形式で行われる。
イタリア
セリエAの下位3クラブがセリエBに自動降格。セリエBの上位2クラブがセリエAに自動昇格し、3位から6位までのクラブでプレイオフを行う。ただし3位と4位の勝ち点差が10以上ある場合は3位のクラブが自動昇格する。プレイオフは3位と6位、4位と5位でホームアンドアウェー形式で戦い、イングランドとは異なり決勝もホームアンドアウェー形式。
変更される?
参考: http://ameblo.jp/ovest-tifosi29/entry-11620370558.html
スペイン
プリメーラ・ディビシオン(一部)の下位3クラブが自動降格。セグンダ・ディビシオン(二部)の上位2クラブが自動昇格し、4位から6位までのクラブでプレイオフを行う。プレイオフは3位と4位の勝ち点差による免除以外はイタリアと同じ形式。
オランダ
かなり変則的。エールディヴィジの最下位は自動降格し、エールステディヴィジの1位が自動昇格。
プレイオフへは、エールディヴィジから16位と17位のクラブが、エールステディヴィジからはレギュラーシーズンの6節ごとに決められるピリオドチャンピオン6クラブと、レギュラーシーズンの上位2クラブが参加する。
プレイオフはシーズン順位を元にした組み合わせによるホームアンドアウェー形式。勝ち残った2クラブが昇格。
追記
セリエBの制度が変更されるかもしれないリンクを修正
rails 4 で任意のテーブルのみ YAML で dump する
rails3 で任意のテーブルのみ dump できる fm_yaml_db(0.2.3) は、rails4 に対応していないのか動きません。
rails4 に対応した yaml_db を使います。
gem 'yaml_db', github: 'jetthoughts/yaml_db', branch: 'rails4'
dump するテーブルを返すメソッドをオーバーライド
config/initialize/dump_tables.rb
module SerializationHelper class Dump def self.tables %w(tables1 tables2 tables3) end end end
もしくは以下のようなメソッドを用意して
def override_dump_tables(*tables) SerializationHelper::Dump.define_singleton_method "tables" do tables end end
適宜書き換えるのも良いかもしれません。
namespace "db:data:dump" do task :set => :environment do override_dump_tables("tables1", "tables2", "tables3") Rake::Task["db:data:dump"].invoke end end
ポリモーフィックなコントローラー
Commentクラスはポリモーフィック関連 commentable を持ちます。
class Comment < ActiveRecord::Base belongs_to :commentable end
class Cat < ActiveRecord::Base has_many :comments, :as => :commentable end
class Dog < ActiveRecord::Base has_many :comments, :as => :commentable end
/cats/:id/comments や /dogs/:id/comments に対応する CommentsController では、commentable_type が Cat なのか Dog なのか判定する必要がありますが、request.path や params[:*_id] などからこれを判定するのはいまいち。
そこで考えた。
resources :cats do member do resources :comments, :defaults => { :type => Cat } end end resources :dogs do member do resources :comments, :defaults => { :type => Dog } end end
こうすることでコントローラーではこのように書けます。
class CommentsController < ApplicationController def index @commentable = params[:type].find(params[:id]) @comments = @commentable.comments end end
ただし、この routing の設定では /cats/:id/comments/:id のようにcommentable の ID と comments の ID の複数が必要なときに commentable の ID が取得できなくなってしまいます。
resources :dogs do resources :comments, :defaults => { :type => Dog } end
とすれば params[:dog_id] と params[:id](コメントのID)が設定されます。
class CommentsController < ApplicationController before_action :commentable_id def show @commentable = params[:type].find(@commentable_id) @comment = Comment.find(params[:id]) end private def commentable_id @commentable_id = params.find{ |key, value| key =~ /_id$/ }.last end end
FriendlyID 日本語の slug が変
日本語の文字列から slug を作成しようと、User.each(&:save) とすると"-f9f3789a-daec-4156-af1d-fab81aa16ee5" のような意味不明な slug が作成されてしまう。
どうやら slug の生成に parameterize という ActiveSupportのメソッドを噛ませているらしく、日本語にこのメソッドを呼び出すと空文字となってしまう。日本語はすべて空文字となり他のレコードと重複するので、それを回避するためユニークな文字列を付け加えているようだ。
回避するには normalize_friendly_id メソッドをオーバーライドする。
class User < ActiveRecord::Base inlucde FriendlyID friendly_id :name, :use => :slugged def normalize_friendly_id(string) # この場合 string は name string.gsub(/[\.\s]/, "-") end end
Sqale を使ってみた
heroku の PostgreSQL 1万行制限に苦しんでいました。heroku は月額 $9 で10,000,000行まで増やせるのですが、コスパがちょっと・・・東京リージョンの VPS か PaaS を借りようかと悩んでいたところに登場したのがSqale の無料キャンペーン。さっそく飛びついてみました。
良いところ
すべて日本語。問い合わせも日本語でOKなのが嬉しい。要望には迅速に対応してくれるようです(無料キャンペーンで忙しいのかメールの返信はまだないけど、言ったところは修正されてた)。なので、以下の気になったところも今後改善されるかもしれません。
気になったところ
- /assets/ 以下のファイルの扱い
gzip圧縮転送できません。またCache-Controleヘッダも吐かない。最初にアクセスしたときに圧縮されていないjs/cssを読み込むことになるので、東京リージョンだしと期待していたよりも速くならなかったのは多分これのせい。
追記
現在はgzip圧縮されるようになりました
- ドメインを複数設定できない
ひとつしか設定できないようで、設定外のドメインでアクセスすると 400 Bad Request となってしまう。静的ファイルをサブドメインで扱いたいときや、WWW有り無しをアプリケーションでコントロール(リダイレクト)して統一したいときに困ります。
メモ
http://mizzy.org/blog/2012/11/05/1/
- Net::SSH で接続できない
これは自分の環境固有の問題かもしれませんが、Capistrano や Net::SSH から Sqale の ssh に接続すると、コンソールが表示されたところで固まってしまいます。いちいち手動で ssh でログインしてアプリ再起動とか面倒・・・
- heroku db:push/pull みたいなのがない
面倒なのでyaml_dbを使ってhttp経由で更新出来るようにしてしまった。PaaSなのになんか違う・・・
それできるよ!とかの情報があれば是非教えてください。
Sqaleは使ってみて全体的に良い感じなので期待しています。