seriaraizeデータに簡単にアクセスする方法

seriaraizeは場合によっては非常に便利な機能だけどそのままではフォームを作る時など面倒だよね。
だから以下のようなコードを書いてみたよ。

class Line < ActiveRecord::Base
  belongs_to :record
  serialize :value

  def method_missing(name,*args)
    if record.data_definitions.detect(){|d| d.name == name.to_s }
      self.value[name.to_s] if self.value
    elsif record.data_definitions.detect(){|d| "#{d.name}=" == name.to_s }
      self.value = Hash.new unless self.value
      self.value[name.to_s[0..-2]] = args[0]
    else
      super
    end
  end

end

ほかのクラスは以下のようになっている。
それぞれ持っているのは"name"カラムだけ。

class Record < ActiveRecord::Base
  has_many :data_definitions
  has_many :lines
end

class DataDefinition < ActiveRecord::Base
  belongs_to :record
end

このようにすることにより、通常のアトリビュートと同様に

<% form_for(@line) do |f| %>
  <%= f.error_messages %>
  <% @record.data_definitions.each do |data| %>
  <p>
    <%= f.label data.name %>
    <%= f.text_field data.name %>
  </p>
  <% end %>
  <p>
    <%= f.submit 'Update' %>
  </p>
<% end %>

のような形でフォームを作ることができるよ。
DataDefinitionに型情報を定義しておけば

<%= f.send data.form_type,data.name %>

などとすると型情報にあったフォームを作ることができるよ。

Railsでリアルタイムフォームバリデーションする

UIを作るときリアルタイムでフォームのエラーチェックをすることは多いよ。
そんなときは以下のようなコードを使うと上手く行くかも。

#model
  def validate_for_ajax n,v
    if attribute_names.find{|i| i == n}
      @attributes[n] = v
      valid?
      errors.on(n) ? "ng" : "ok" 
    else
      nil
    end
  end

#controller
  def valdiate_attribute
    @model = Model.find __some_find_info__
    render :text => @model.validate_for_ajax(params[:attribute], params[:value])
  end

#view
    observe_field form_id,
                  :url => {:action => :valdiate_attribute},
                  :with => "'attribute=ATTRIBUTE}&value=' + value",
                  :complete => "$('EDIT_ID').className = request.responseText;"

これでフォームの値によってedit_idのクラスをokとngを切り替えることができるよ。

[ruby]Authlogic

コンソールでユーザーを作ってた後、ログインできるか試そうとすると、以下のエラー。

UserSession.new(:login => "test", :password => "123456")

You must activate the Authlogic::Session::Base.controller with a controller object before creating objects

調べたところ事前に

Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::RailsAdapter.new(UserSession)

と行わないとダメらしい。

class << helper; self; end

RSpec

class << helper; self; end

というコードが引っかかっていたんだけど、やっとすっきりした。

class Foo
  class << self
    #something
  end
end

というような特異クラス宣言と同じなんだ。
そして内部にある"self"は特異クラスを戻り値とするための文なんだ。