Rails勉強会@関西6

Posted by nanki Sun, 21 Jan 2007 20:51:00 GMT

土曜日は、Rails勉強会に行ってきました。

今回は、初心者レッスンの担当。

朝8時に起きて準備するはずが、前日5時くらいまで(というか、三時間前まで)いろいろやっていたので、目覚まし時計の思いも届かず、2時間寝坊。 ひげを剃るのも会場で。 11時到着に合わせて計算していたので、なんとか12時前にはたどりつけたけど、あせったなぁ。

発表は、なんとか終了。 途中で場内を回ってみると、思いの外、進み具合がバラバラだったので、最後の部分は演習時間を延長してカット。

なにから解放されたのか、昼御飯は食べる気も起こらなかったのに懇親会まではずっとお腹が鳴りっぱなしなのでした。

終わってから気がついたけど、初期のRails勉強会のように、教科書になるような本を写経とかでもいいんじゃないか、と思えてきた。
毎回、目的のテーマにたどり着くまでに、ActiveRecord, scaffold の道を進まねばならないので、なんとも大変。 三回目なので、シリーズ化はまだ止められそうだし。

「RailsでXML-DBにチャレンジ」by モバイル通信兵さん

おもしろそう。 DB2要求されるのが、ちょっとハードル高め。 使えそうな場所を探してみようっと。

「Rubyist SNS の実装について」by かずひこさん

最近コミットできてなくて申し訳ないです。 会場で、updateしていつものように一人で友達作って・・・
この作業がいつも寂しい。

「rails tips」by 氏久さん

<%=h %>は、エディタのショートカットで出せるように設定していて、<%= %> にするには、hを削らないといけない、という安全スイッチがあるので、少人数での開発の場合はまあいいかな。 jitor は楽しそう。

「やさしいRailsの育て方(仮題)」by 西和則さん

DBモデリング?のお話。 火星エステ理論なる判別法で、本質的な項目を洗い出せ!

火星の鈴木さん(だっけ?)で何故か火星年代記を思い出してしまった。

懇親会は、内装がゴージャスなお店。

二次会では、非カラオケチームに合流しようとして連絡をしたら、途中で携帯の電池が切れてしまって、結局合流できなかった・・・。 今朝、僕の目を覚まそうとして、一時間に渡ってブルブルしてたはずだから、当然なのかも。

なので、はぐれ組三人で、駅前のサンマルクカフェで、お話しました。

Posted in , ,  | Tags ,  | no comments | no trackbacks

ActiveRecord - フォーマット

Posted by nanki Wed, 27 Dec 2006 12:09:00 GMT

小分けにしないとサーバが止まる・・・

model_formatter
  • 特定のカラムを、フォーマット付きでアクセス。
  • formatted_weight で、フォーマット済みのweightにアクセス。
  • フォーマット済み属性の名前は、:formatted_attr, :prefixで変更。
  • class Widget < ActiveRecord::Base
      # FormatInteger という名前のFormatterでフォーマットを指定
      # :boolean, :currency, :decimal, :integer, :percent, :phone が定義済み
      # :as には、Formatterのインスタンスも指定できる
      format_column :weight, :as => :integer
      
      # Procを使って
      format_column :weight, 
        :formatted_attr => :formatted_weight,
        :options => {:delimiter => ','},
        :from => Proc.new{|attribute, options| ... },
        :to   => Proc.new{|str, options| ... }
      
      # ブロックによる定義も
      format_column :weight do
        def from(attribute, options)
          # ...
        end
      
        def to(str, options)
          # ...
        end
      end
    end
      
    w = Widget.new(:weight => 12345)
    w.formatted_weight # => 12,345
    # 書き込みもできる!
    w.formatted_weight = '54,321'
    w.weight # => 54321
auto_convert_fields
  • attribute=を定義。
  • class MyModel < ActiveRecord::Base
      # name=, :text= の前に、TextHelper#strip_tags をはさむ。
      auto_convert :name, :text, :with => :strip_tags
      
      # 同じ
      auto_convert :name, :text do |value|
        strip_tags(value)
      end
    end

Posted in , ,  | Tags , ,  | no comments | 2 trackbacks

:yの悲劇

Posted by nanki Thu, 21 Dec 2006 09:51:00 GMT

GPS情報を格納するのに、

class Entry < ActiveRecord::Base
  has_one :location
end

class Location < ActiveRecord::Base
  # 実際にはGeometry型で格納するので、アクセサを定義
  def x
    point.x
  end
  def y
    point.y
  end
end

こんなモデルを作ると・・・

$ script/console
>> entry = Entry.find(:first)
>> entry.location.x
=> 135.0
>> entry.location.y
=> 35.0
>> entry.location.send :x
=> 135.0
>> entry.location.send :y
ArgumentError: wrong number of arguments (0 for 1)
        from (irb):35:in `y'
        from (irb):35:in `send'
        from (irb):35

xは大丈夫なのにyはだめ?

yの正体は、pのようにyamlを吐くprivate method、Kernel#y in yaml.rb。 何故だ?

entry.location の中身は、実はAssociationProxyで、ActiveRecordのソースを見るとこんな風になっている。

# lib/active_record/associations/association_proxy.rb
module ActiveRecord
  module Associations
    class AssociationProxy #:nodoc:
      attr_reader :reflection
      alias_method :proxy_respond_to?, :respond_to?
      alias_method :proxy_extend, :extend
      instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?|^proxy_respond_to\?|^proxy_extend|^send)/ }

entry.location.send :x すると、AssocationProxy#xが無いのでtargetにsendされるが、entry.location.send :y だと、Kernel#yが見つかってしまうのか・・・

当然entry.location.target.send :y だとうまくいく。

Ruby1.9 だとsendの仕様が違ってうまくいきそう。

Posted in , ,  | Tags ,  | 4 comments | no trackbacks

svn:externals のリビジョン固定

Posted by nanki Sun, 03 Dec 2006 02:01:00 GMT

Railsで $ script/plugin install -x したプラグインのリビジョンを固定するには、

$ svn propedit svn:externals vendor/plugins/

として、

plugin_name  -r150  svn://example.com/path

とやればよいらしい。

参考

subversion - 外部定義

Posted in ,  | Tags ,  | no comments | 1 trackback

Rails Plugin - View系2

Posted by nanki Wed, 04 Oct 2006 21:55:00 GMT

MenuEngine
  • DHTMLのメニューを作る。
  • # in config/environment.rb
    module ApplicationHelper
      include MenuHelper
    end
      
    # in app/helpers/application_helper.rb
    module ApplicationHelper
      include MenuHelper
    end
  • module MenuEngine
      # UserEngineと連携
      # trueで許可されないcontroller/actionへのメニューが表示されなくなる
      config :access_control, false
      # エフェクトの設定。element はメニューを指す。
      config :on_show, "new Effect.Appear(element);"
      config :on_hide, "new Effect.Fade(element);"
    end
  • module ApplicationHelper
      def my_menu
        item0 = MenuItem.new(:text =>  "Users", :controller => "user")
        item1 = MenuItem.new(:text =>   "List", :controller => "user", :action=>"list")
        item2 = MenuItem.new(:text => "Images", :controller => "image")
      
        item0.items << item1
        [item0, item2]
      end
    end
  • <%= engine_stylesheet "menu_engine" %>
    <%= engine_javascript "menu_engine" %>
    ...
    <%= menu :menu => my_menu, :layout => :vertical %>
  • YAMLで設定する方法もある。

Posted in , ,  | Tags , ,  | no comments | no trackbacks

Rails Plugin - ActiveRecord拡張系2

Posted by nanki Tue, 29 Aug 2006 07:24:00 GMT

acts_as_modified
  • 変更のあった属性を検知。
  • モデルに
    acts_as_modified
  • :clear_after_save => trueを指定すると、save後はmodified?trueじゃなくなる。
  • person = Person.find(:first)
    person.age # 100
    person.age = 10
    person.age_modified? # true
    person.original_age # 100
    person.modified_attributes # {:age => 100}
      
    # restore
    person.restore_attributes :only => :age
    person.age # 100
      
    # clear
    person.clear_original_attributes :only => :age
      
    # dbと比較
    person.modified?(:reload) # true
acts_as_bookmarkable
  • migrate はリンク先参照。
  • class Post < ActiveRecord::Base
      acts_as_bookmarkable
    end
      
    post.add_bookmark(Bookmark.new)
    だけ。
  • 構成はacts_as_commentableとほぼ同じ。
acts_as_commentable
  • class Post < ActiveRecord::Base
      acts_as_commentable
    end
    で、コメントがつけられるようになる。
  • post.add_comment(Comment.new(:title => "..."))
    とか。
  • 実装は:polymorphicbelongs_toを使ってると思う。
acts_as_sluggable
  • URLがhuman readable(とは限らないが)に。
  • class Article < ActiveRecord::Base
      acts_as_sluggable :with => 'title'
    end
      
    url_for :controller => "articles", :action => 'show', :id => @article
    # => "/articles/show/76-omg-my-cat-is-so-cute-lol"
  • to_param というメソッドを上書きしてるらしい。
acts_as_sequenced
  • ASP型のCRMアプリを作ろうとした時に、アカウント毎に連続な管理番号を振りたかった。下のコード参照。
  • acts_as_listだと、連番になるが、削除すると詰められるのでダメ。
  • class Account < ActiveRecord::Base;end
      
    class Customer < ActiveRecord::Base
      acts_as_sequenced 
        # 連番
        :column => :customer_number,
        # 有効範囲
        :scope => :account
    end
      
    class Job < ActiveRecord::Base
      acts_as_sequenced :column => :job_number, :scope => :account
    end
    これで、Account毎に連番が。
  • プラグインの形では提供されてないので、コードをlib/以下にコピペして、environment.rbでrequireしてね。
  • コードからは、削除して追加すると、過去の管理番号と重複する番号が割り当てられるように見える。(これはうれしくない)
  • acts_as_paranoid(削除フラグで削除したかの用に見せるプラグイン)と併用できるようになっていて、併用すればこの問題は起こらなさそう。
acts_as_most_popular
  • class Person < ActiveRecord::Base
      # attribute :name
      acts_as_most_popular :limit => 3
    end
      
    # すると、頻度の高い順に3個とってこられる。
    Person.most_popular_names # => ["Jajamaru", "Piccolo", "Porori"]
  • nameが複数形になるってどういうことよ。
acts_as_network
  • SNS用途?
  • class User < ActiveRecord::Base
      acts_as_network
        :join_table => :friends,
        :source_key => :user_id,
        :destination_key => :friend_id
    end
      
    alice, bob = User.find([1,2])
      
    # bobはaliceの友達です
    alice.connections << bob
      
    # bobはaliceの2です
    alice.connections.push_with_attributes(bob, :role => 2)
    alice.connections.find(bob.id).role # => 2
      
    # bobはaliceの友達ですか?
    alice.connections.include?(bob) # => true
      
    # aliceは誰の友達ですか?
    alice.connections.all_in
acts_as_rateable
  • acts_as_ratableの方がよさそう。(こっちは複数人で点数をつけられない)
  • tのあとのeがあるかないかの違い・・・
  • # db/migrate/*.rb
      def self.up
        create_table :ratings do |t|
          t.column :rating, :integer
          t.column :rateable_id :integer, :null => false
          t.column :rateable_type, :string, :null => false
        end
        add_index :ratings, [:rateable_id, :rating]
      end
        
      def self.down
        drop_table :ratings
      end
    end
  • class YourModel
      acts_as_rateable
    end
      
    # 5点をつける
    m.rate(5)
    m.rating = 5
      
    # 5点
    m.rating # => 5
      
    # 最初に見つかった3点のもの
    YourModel.find_by_rating(3) 
    # 3点以上のもの全部
    YourModel.find_all_by_rating(3..-1)
    # 1点または3-5点のもの全部
    YourModel.find_all_by_rating([1,3..5])
acts_as_ratable
  • ドキュメント無し。以下ソースから読み取り。
  • たぶん、Rating.create_tableで必要なテーブルが出来る。Rating.drop_tableでテーブルをdrop。
  • たぶん、
    class YourModel
      acts_as_ratable
        :within => (1..5), # 点数の範囲
        :by => User        # 採点者のクラス? 指定しないと、点数は毎回上書きされる
    end
      
    # current_userが5点をつけました
    m.rate_as(5, :by => current_user)
      
    # current_userによって付けられた点数
    m.rating_by(current_user)
      
    m.average_rating # => 平均点
    m.raters         # => 採点者
  • 同じユーザが同じものに採点すると上書きされる。
acts_as_popular
  • class YourModel
     acts_as_popular
     has_and_belongs_to_many :tags, :update_popularity => true
    で、popularityフィールドが更新される。(counter cacheみたいなのだと思う)
acts_as_searchable
  • HyperEstraierで全文検索。
  • app/models/model.rbに
    class Article
      acts_as_searchable
    で、
    Article.fulltext_search('biscuits AND gravy')
    全文検索できるようになる。
acts_as_rast_indexed
  • なんてのもあるみたい。
  • 一応プラグイン。差分を配布みたいな形態みたいだけど。
acts_as_ordered
  • acts_as_ordered :order => 'first_name', :wrap => true
  • で、モデルが順序付きに。
  • person.next
    で、次のレコードをとってこられる。:wrap => true の場合は、最後まで行ったら最初に戻る。
acts_as_taggable
  • モデルがタグ漬けに。
  • tags,taggings テーブルを作成。
    create_table :tags do |t|
      t.column :name, :string
    end
    create_table :taggings do |t|
      t.column :tag_id       , :integer
      t.column :taggable_id  , :integer
      t.column :taggable_type, :string
    end
  • taggable.tag_with("frog animal")
    Taggable.find_tagged_with "frog"
acts_as_versioned
  • モデルがバージョニングに対応しちゃう
  • page = Page.create(:title => 'hello world!')
    page.version       # => 1
    page.title = 'hello world'
    page.save
    page.version       # => 2
    page.title         # => 'hello world'
    page.revert_to(1)
    page.title         # => 'hello world!'
    こんな感じ。
acts_as_paranoid
  • paranoid とは偏執狂のこと
  • 削除する時に削除フラグ(ちょと違うけど)を使うようになる
  • 忘れてしまいがちなフラグの指定も、普通にfind するだけで勝手に付く
  • find_with_deleted で削除されたものも検索対象に
acts_as_bitfield
  • acts_as_bitfield :bitfield, :fields => [:one, :two]
  • 実際のテーブルには整数値型の bitfield が定義されている。
  • :one ,:two にはtrue/falseが格納でき、model.one, model.two といった形式でアクセスできる。
  • model.one => true, model.two => true の時、 model.bitfield => 3
acts_as_deque
  • 先頭と末尾に対して追加/削除できるようになる。enqueue/dequeue, push/pop など。
  • 双方向リストで格納される。
  • scope を使えば、複数のqueueも扱える?
acts_as_attachment
  • アップロードしたファイルを管理する。
  • ファイルシステム or DBにバイナリとして保存。
  • サムネイルを複数生成できて、サムネイルは元画像を親として参照できる。
  • まだ開発中らしい。
  • vendor/plugins/acts_as_attachment/test/schema.rb を参考にテーブルを作成して、対応するモデルにacts_as_attachment.
  • ファイルで保存するときは、:storage => :file_systemを指定。DBが楽。
  • attachment.uploaded_file = params[:attachment_file]
    で更新。
  • formをmultipart にするのもお忘れなきよう。
better_nested_set
  • acts_as_nested_setをより便利に。
  • root が一個の場合を想定している。→ 複数の場合はacts_as_threaded
  • →rootsというメソッドがある。
  • class Model
      acts_as_nested_set
    end
  • def self.up
      add_column :models, :parent_id, :integer
      add_column :models, :lft, :integer
      add_column :models, :rgt, :integer
    end
  • migration などで追加する場合は、Model.renumber_allで、必要な値を更新。
acts_as_threaded
  • ドキュメント無し, ムービーあり。
  • zipを採ってきて自分でインストール。
  • 掲示板などで使うツリー状スレッドを実現する。
  • 一回のクエリーで、というところがミソ。
  • def self.up
      add_column :models, :parent_id, :integer
      add_column :models, :root_id, :integer
      add_column :models, :lft, :integer
      add_column :models, :rgt, :integer
      add_column :models, :depth, :integer
    end
  • そのままだと、parent_idに0を指定しないとエラーが出るので、こんなパッチを当てて。
  • --- vendor/plugins/acts_as_threaded/lib/threaded.rb.orig
    +++ vendor/plugins/acts_as_threaded/lib/threaded.rb
    @@ -70,7 +70,7 @@
             end
      
             def after_create
    -          if self.parent_id.zero?
    +          if self.parent_id.blank? || self.parent_id.zero?
                 self.reload # Reload to bring in the id
                 self[root_column] = self.id
                 self.save
acts_as_ldapable
  • ActiveRecordを拡張する意味がよくわからないけど、LDAPにアクセス(取得/更新)できるようになるらしい。
  • 本体が見あたらない・・・
acts_as_habtm_list
  • acts_as_list のhas_and_belongs_to 版。
  • 間に多対多の関係テーブルがあるような場合に、順序付きリストを管理。
  • has_and_belongs_to_many :categories
    acts_as_habtm_list :scope => :categories
acts_as_shellable
  • コマンドラインから使いやすくするための機能。
  • Tag.find_by_name('funny').persons
    Tag.find_by_name('funny') & Person.find_by_occupation('judge')
    Person.my_find_all('tags=funny')          # tagsは、tags.name(name はデフォルト設定)
    Person.my_find_all('c3=judge tags=funny') # c3 は三番目のカラムのalias
    に。
  • デフォルト値を複数設定することによって簡略化されているので、ぴったりはまらないと使いにくいかも。
acts_as_enumerated
  • 値と名前のペアになったテーブルを、他のフィールドの値として使いたい場合に使う。
  • class Booking < ActiveRecord::Base
      has_enumerated :status, :class_name => 'BookingStatus'
    end
    class BookingStatus
      acts_as_enumerated
    end
    ...
    Booking.new(:status => BookingStatus[:provisional])
  • 実際にはstatus_id:provisionalに対応するidが格納される。

Posted in , ,  | Tags , ,  | no comments | 1 trackback

バーコード大作戦(予告編)

Posted by nanki Mon, 10 Jul 2006 07:13:00 GMT

がーん。

バーコードペディア:Webカメラでスキャンできる製品情報コミュニティ - Engadget Japanese

以前からbarcoder.nuとしてやっていたところがコンセプトをちょっと変えてみた?よう。

半年くらい天日干しにしている社内プロジェクトがあって、それがちょうどこんなコンセプトなんです。

demo QuickTime:2.4MB

というわけで頑張って今月中にでもリリースします。と書いて、自分のお尻に火をつける。

点スイッチ有限会社の最初のサービスとしてリリースできるといいな。

リンク先がないのにリンクを張るのは、早く会社のサイトを作らなきゃ、というプレッシャーです。

あ、もちR on Railsです。

Posted in , , , ,  | Tags ,  | no comments | no trackbacks

Rails Plugin

Posted by nanki Tue, 25 Apr 2006 14:35:00 GMT

全部終わったら公開しようと思っていたけど、全く終わる気配がないので公開します。

今回は量が多いので分割しました。

全部見たい人は、 タグ:rails_pluginでどうぞ。

Posted in , ,  | Tags , ,  | no comments | no trackbacks

Rails Plugin - ActiveRecord拡張系

Posted by nanki Tue, 25 Apr 2006 14:30:00 GMT

composite_primary_keys
  • 主キーとして複合キーを扱える。
  • $ gem install composite_primary_keys
  • require 'composite_primary_keys'
      
    class Road < ActiveRecord::Base
      belongs_to :attribute, :foreign_key => [:attribute_code, :mesh_code]
    end
      
    class Attribute < ActiveRecord::Base
      set_primary_keys :attribute_code, :mesh_code
    end
      
    Road.find(:first).attribute #=> SELECT...WHERE roads.attribute_code = attributes.attribute_code and roads.mesh_code = attributes.mesh_code ...
pessimistic locking
  • Account.transaction do
      account = Account.find(:first, :lock => true)
    end
      
    Account.transaction do
      account = Account.find(:first)
      account.lock
      # ...
    end
    で悲観的ロックができる。
  • Edgeには取り込まれたっぽい。
has_many_polymorphs
  • Rails標準の :polymorphic では、逆向きの参照が出来ない、などの制限がある。
  • 記述も少なくなる。
  • 詳しい経緯
  • 下のように変わる。あってる?
  • # Rails
    class Dog < ActiveRecord::Base
      has_many :eater_petfoods, :as => :eater
      has_many :petfoods, :through => :eater_petfoods
    end
      
    class Cat < ActiveRecord::Base
      has_many :eater_petfoods, :as => :eater
      has_many :petfoods, :through => :eater_petfoods
    end
      
    class EatersPetfood < ActiveRecord::Base
      belongs_to :petfood
      belongs_to :eater, :polymorphic => true
    end
      
    class Petfood < ActiveRecord::Base
      has_many :eater_petfoods
      has_many :eaters, :through => :eater_petfoods # これができない
    end
  • # has_many_polymorphs
    class Dog < ActiveRecord::Base;end
    class Cat < ActiveRecord::Base;end
      
    class EatersPetfood < ActiveRecord::Base
      belongs_to :petfood
      belongs_to :eater, :polymorphic => true
    end
      
    class Petfood < ActiveRecord::Base
      has_many_polymorphs :eaters, :from => [:dogs, :cats]
    end
  • eaterが増える度にPetfoodを書き換えないといけないのがかっこよくない。
store_multiplied
  • DBに保存される値が何倍かになる。アクセサでアクセスするときは何分の一かになる。
  • class YourModel
      store_as_millis :field
    end
    YourModel.find(:first).field # => 22.222
    # DBには22222で格納されている
  •   store_as_decis  :field # * 10
      store_as_cents  :field # * 100
      store_as_millis :field # * 1000
  • 元の値が欲しい時は
    m.attributes.fetch 'field'
force uppercase
  • force_uppercase :include_text => true
    
    で、指定したcolumnが大文字に。:include_text => trueで、:string型のみならず:text型も大文字に。
  • :only, :except が使える。
ActiveCrypto
  • $ gem install ezcrypto
  • config/enviroment.rb でrequire.
  • class Document
     encrypt :title
    で、モデルの属性を暗号化。
  • doc.enter_passward = 'abc'
    で、パスワードを設定すると、encription/decriptionが透過的に行われる。
UpdateHabtmAttributes
  • has_and_belongs_to_many の関連テーブルに持たせたアトリビュートを書き換えられる。
  • collection.push_with_attributesのupdate版?
  • ファイルがないよ~。各自でinit.rbを書いてくれということかな。
allow_habtm_primary_key
  • has_and_belongs_to_many のjoin tableにidという名前のフィールドを持たせると、もとのオブジェクトのidで上書きしてしまう問題を解決?
  • has_and_belongs_to_many :members, :join_table_primary_key => "id"
  • join_tableに対してモデルを作れるようになるので、User,Bookが多対多になってるときに、個人が自分用のレビューをつけるときとか。そういうのが欲しい人には便利。
  • :join_table_primary_key => "id"
    は、svn版↓では要らない。idに固定。
  • 使ってみたけど、だめっぽい・・・
  • svn://suven.no-ip.org/rails/plugins/allow_habtm_primary_key
userstamp
  • created_on, updated_on で自動的に日付が入るように、created_by, updated_by で、ログイン中のユーザの情報が自動的に入る。
  • テーブルに、created_by, updated_by カラムを付け足して、
    class User < ActiveRecord::Base
      cattr_accessor :current_user
    end
      
    class ApplicationController < ActionController::Base
      before_filter do |c|
        User.current_user = User.find(c.session[:user].id) unless c.session[:user].nil?
      end
    end
      
    class Post < ActiveRecord::Base
      belongs_to :created_by, :class_name => "User", :foreign_key => "created_by"
      belongs_to :updated_by, :class_name => "User", :foreign_key => "updated_by"
    end
active form
  • 非ActiveRecordモデルに対するvalidationなどを支援。
  • formだけでテーブルはない、というデータにvalidationを使いたい、という時に使う。
  • class Search < ActiveForm みたいに使う。
riff
  • ActiveRecord 同士の差をとってくれる。
  • a = Person.create :name => 'alice', :age => 20
    b = Person.create :name => 'bob', :age => 21
    a.diff?(b)   # => true
    a.diff(b)    # => {:name => ['alice', 'bob'], :age => [20, 21]}
enforce_column_limits
  • enforce_column_limits とやると、テーブルの情報から最大文字数のvalidationを自動でやってくれる。
validates_numericality_of
  • validatess_numericality_of を拡張して、:gt => 0, :odd, :even などで、数値の大小、偶奇によるvalidationが行えるようになる。
ActiveSearch
  • あるモデルの指定したフィールドについて、indexを作成し、検索を行うのを支援する。
  • デフォルトでは、以下の三つのIndexerが使えるらしい。
    • 指定したフィールドにindexを格納する。
    • ferretを使って、ファイルにindexを格納する。
    • 別のテーブルにindexを格納する。
Spatial Adapter
  • GeoRuby が必要。gemあり。
  • PostGIS,MySQLのGeometryカラムが扱えるようになる。
  • svn://rubyforge.org/var/svn/georuby/SpatialAdapter/trunk/spatial_adapter
  • MySQL5.0.16以前はMyISAM engine のみ。(MySQLの制限)
  • 空間型カラムを条件とした検索は手動で書く。
    • find_by_*が使えるようになったっぽい。(矩形での検索のみ)
      Park.find_by_geom(LineString.from_coordinates([[1.4, 5.6], [2.7, 8.9], [1.6, 5.6]]))
      Park.find_by_geom([[3, 5.6], [19.98, 5.9]])
  • the_geomを読む度にGeometry型に変換するので、次のようにしないと値の更新ができないらしい。
    place = Place.find(:first)
    the_geom = place.the_geom
    the_geom.y = 123456.7
    place.the_geom = the_geom
  • テスト用のfixtureに使いたい場合はこう。
    first:
      id: 1
      point: <%= GeoRuby::SimpleFeatures::Point.from_x_y(0, 0).to_fixture_format %>
settings
  • アプリケーション全般に関わる設定を保存するためのグローバルなハッシュみたいなものを提供してくれる。
  • pluginをインストールした後、
    $ ruby script/generate settings_migration
    $ rake migrate
  • Settings.foo = 'bar'
    Settings.foo # => 'bar'
    Settings.all # => {'foo' => 'bar'}
    Settings.destroy :foo
    Settings.foo # error
autoescape
  • ActiveRecordを拡張して、デフォルトでHTMLescapeが行われた値を返すようにする。
  • viewなどでhを使っている場合は二重でエスケープされるので、はずすように。
  • フォームの初期化などでエスケープされると困るときは、生データを取得する方法が用意されている。
  • acts_as_raw :column, ... で生データ。
  • @item.name_raw みたいな方法でも生データ。
  • RubyForge
  • svn://rubyforge.org//var/svn/autoescape
deadlock_retry
  • ActiveRecordが、デッドロックで失敗したトランザクションを自動的にリトライするようになる
  • コードの変更は必要ない
  • 今のところMySQLでのみテスト
calculations
  • group by を使った構文が書ける
  • User.calculate(:count) といった感じ
  • たぶん、:max, :min などもあるだろうな。
  • Order.calculate(:sum, :cost).group_by(:country).having {|sum| sum > 50}
    SELECT country, SUM(cost) FROM orders GROUP BY country HAVING SUM(cost) > 50
    になる!?
guid
  • class MyModel < ActiveRecord::Base
      usesguid
      ...
    とすると、ID(デフォルト)フィールドに22文字の、URLに使っても大丈夫なGUIDが生成されるようになる。
  • システムの中でuniqueってことだよな。
where
  • findの検索条件をキレイに書ける
  • Model.find_with_conditions(:all) do
      year '>', 2005
      name 'like', 'Foo%'
    end
    こんな感じ。
  • 条件をCondクラスのインスタンスに保存しておけば、cond.whereActiveRecord::Base#find の条件として使える。
count_limit_associations
  • Model.count にて、:include を指定した場合でも、Modelの数が数えられる(普通はjoinによって行が増える)
  • paginate でも:include が使えるように
  • Rails本体に取り込まれるかも(pending patch)
  • 1.13.2には取り込まれてない。
file_column
  • app/models/model.rb に
    file_column :image
  • <%= file_column_field “entry”, “image” %> でアップロード用のフォームフィールドを生成
  • <%= image_tag url_for_file_column(“entry”, “image”) %> で参照。
  • RMagick を使って、自動的にリサイズを行ったり、複数のサイズを生成したりできる。
    file_column :image, :magick => {:geometry => "640x480>"}
    file_column :image, :magick => {
      :versions => {"thumb" => "50x50", "medium" => "640x480>"}
    }
filters_column
  • ドキュメント無し
  • ActiveRecordを拡張して、保存時に指定したフィールドにフィルタがかけられるようになる模様。
  • コメント欄でtextile記法が使えるようにする時とかに使うのかな?
filtered_column
  • filtered_column :name, :only => [:textile_filter, :smartypants_filter]
    で、name_html, というフィールドにfilterされた値が格納される。
  • filtersというテキスト型のカラムを追加しないとだめ?(何に使ってるのかよくわらかない)

Posted in , ,  | Tags , ,  | no comments | no trackbacks

Rails Plugin - 認証系

Posted by nanki Tue, 25 Apr 2006 14:29:00 GMT

session_timeout
  • class ApplicationController
      session_times_out_in 10.minutes, :after_timeout => :do_something
    end
    で、10分アクセスがないとセッションが切れる。
access_control
  • class SomeModel
      include AccessControl
    で、モデルに対して、アトリビュート単位でのアクセスコントロールが可能。
  • let_read :login, :name, :if => true
    let_access :salt, :cypher, :timezone, :role => 'admin'
  • 同じくコントローラで、
    include AccessControl
      access_control :all, :if => false
      access_control :rss, :if => :is_authorized_for_rss
      access_control :view, :role => '(admin | user) & !blacklist'
      access_control :create, :edit, :role => '(admin | moderator) & !blacklist'
      # runs an arbitrary block
      access_control :motd do |c|
        (c.some_controller_method || c.some_other_method) && (rand > 0.5)
      end
    とすることで、ロールベースのアクセスコントロールができてしまう。
  • プラグイン機構を持っていて、:role オプションはそれで実現されている。parser とか含んでるから、AccessControlの下に直接書くのが忍びなかったんだろうか。丁寧な作り込み。
validates_captcha
  • captcha (人間であることを確認するゆがんだ文字のやつ)
  • “completely automated public Turing test to tell computers and humans apart” の略。
  • $ script/generate captcha config で、設定ファイル config/captcha.ymlが作られる。
  • 設定ファイルにて指定したデータ,画像保存用のディレクトリをmkdir.
  • model に validates_captchaを追加。
  • view のform中で、
    <% c = prepare_captcha -%>
    <%= captcha_hidden_field c, 'your_model' %>
    <%= captcha_image_tag c %>
    <%= captcha_label 'your_model', 'Type in the text from the image above' %>
    <%= captcha_text_field 'your_model' %>
    とすることで、captchaが使えるようになる。
account_location
  • アカウント毎にサブドメインがあるような、スコープ付の認証に。
acts_as_authenticated
  • script/generate authenticated user account で認証機能が作れる
  • メール認証を使ったアクティベーションも作れる
  • generator を使うので、既存のクラスに機能追加するのはできない?
login_engine
  • # in config/environment.rb
    module LoginEngine
      config :salt, "your-salt-here"
    end
    Engines.start :login
    という感じで設定を記述する
  • engines というplugin に依存している
  • 上記を設定してから、
  • $ rake engine_migrate ENGINE=login でDBのスキーマを変更できる。
  • 最近は$ rake db:migrate:engines ENGINE=login
  • メール認証も余裕で対応!
  • さらばlogin_engine
user_engine
  • login_engine をさらに拡張する形で、role ベースの認証を組み込める。
  • Engines.start :login
    Engines.start :user
    login_engineより後じゃなきゃダメ。
ssl_requirement
  • include SslRequirement
    ssl_required :signup 
    とすると、signup が実行される時は、ssl にリダイレクトされる。
security_extensions
  • verify_form_posts_have_security_token を使うと、postされた値が正当なものかどうかチェックできる。
  • secure_form_tag を使ってform の中にsession id をハッシュしたトークンを埋め込んでおいて、セッション中の値と比較する、という仕組み。
  • 元ネタはこちら
sentry
  • 指定したフィールド(主にpassword)の値を暗号化してくれる
  • 暗号化の方式は、いくつか選べるようだ。

Posted in , ,  | Tags ,  | no comments | no trackbacks

Older posts: 1 2 3 4