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
class << helper; self; end
というコードが引っかかっていたんだけど、やっとすっきりした。
class Foo class << self #something end end
というような特異クラス宣言と同じなんだ。
そして内部にある"self"は特異クラスを戻り値とするための文なんだ。