アソシエーションの拡張。
「学習する」というクラスには、主たるメソッドが二つあって、ですね。
「憶える」メソッドと、「学ぶ」メソッド、ですね。
で、「憶える」メソッドは、ぶっちゃけ、あまり楽しくない訳ですわwww
空き領域に、値を放り込むだけですから。
でも、「学ぶ」メソッドは、そりゃあ、もう、アレですよ。
頭の後ろっ側が、ピコーンって光りますよ。
コレこそが、学習することの醍醐味な訳ですよ。
でも、悲しいかな、年男も3度目になりますと、ですね。
脳の構造が硬直化してくるのか、中々、「学ぶ」ということが苦手になってくるようでして。
それは、やっぱり、これまで学んできたことが、経年によって、憶えたことに変わってくるからなんでしょう。
ロジックを学んで、そのロジックを実行してきたことが、やがて、「そのロジックに値を放り込めば、どうなる」ということを、憶えてしまうんですね。
だから、思考の幅が拡がらなくなっていくんですな。
思い込みが有する領域が拡がって、考える領域をどんどんと縮小化していく。
だって、その方が速いから。
新たにロジックを通すよりも、キャッシュされたものを出す方が、速いし楽だし。
往々に、それで正しい結果が得られることの方が多いから。
だから、己の中に蓄積されていないことを新たに身に付けようとしても、中々、身に付かないんだよね。
学ぶ前に、憶えたことで処理しようとするから。
ツマンネwww
で、なんでこんなに長い前フリをするか、というとですね。
まあ、実例なんですけどもwww、以下の通りのモデルが二つあってですね。
class User < ActiveRecord::Base has_many :asked, :foreign_key => 'asked_user_id', :class_name => 'Friend', :dependent => :destroy has_many :was_invited, :foreign_key => 'was_invited_user_id', :class_name =>'Friend', :dependent => :destroy do has_many :asked_friends, :through => :asked, :source => :asked_to has_many :was_invited_friends, :through => :was_invited, :source => :was_invited_from end
class Friend < ActiveRecord::Base belongs_to :asked_to, :foreign_key => :was_invited_user_id, :class_name => "User" belongs_to :was_invited_from, :foreign_key => :asked_user_id, :class_name => "User" end
で、多対多の自己参照で関連付けされている訳ですわ。
んで、Friendモデルには、「state」というカラムがある訳ですよ。
で、User(hogehoge)が、Friendモデルで関連付けされているUserは、script/consoleだったら、
>> @user = User.find_by_nickname("hogehoge") >> @user.asked_friends >> @user.was_invited_friends
で、解る訳ですわ。
両者の論理籍をとれば、Friendモデルで結びつけられた、Userがまとめられる訳ですわ。
>> @friendships = @user.asked_friends & @user.was_invited_friends
で。
じゃあ、hogehogeとfugafugaが関連付けられたFriendオブジェクトのstatusは?
>> @friendship = Friend.find(:first, :conditions => { :asked_user_id => hogehoge.id, :was_invited_user_id => fugafuga.id}) >> @frindship.status
ですな。
じゃあ、Friendモデルで、statusがacceptedなものを集めるのは?
>> @friendships = Friend.find(:all, :conditions => {:state => "accepted"})
じゃあ、User(hogehoge)が関連付けられた、Friendオブジェクトは?
いやいや、悩んだ悩んだwww
そりゃあ、もう、無駄に悩んだよ。
Friendモデルから、asked_user_idかwas_invited_user_idにhogehoge.idが含まれているのを集めて...
いやいや、もう、集まってるんだよね。
>> @user.asked | @user.was_invited
なんで、こんなことに気が付かないの? 俺www
「asked」と「was_invited」が、唯の中間テーブルの役割でしかない、と、思い込んでるの。
外部から参照することが出来ない、と思い込んでやんの。
なんでだよっwww
普通に考えれば、間で値を抜くことが出来て、当たり前じゃんwww
バカじゃね? 俺。
今、ちょっと涙目だよwww
で。
こんなことも気が付かないから、「User(hogehoge)の関連付けられたFriendモデルの中で、stateがacceptedなものを集める」っていうのを考える時に、すっっっっごい手間なことを考えてしまうんだよね。
「んあああああ、総当たりでループ回して、判定して、分岐して、ヒットしたヤツを変数に積むか...」って。
いや、ね?
それ、激しくダサいでしょ?
超低レベルじゃない。
そりゃあ、ね? 内部的にとか、ローレベルなところで考えれば、総当たりループしているような処理なんて、山ほどあるでしょうよ。
でも、それじゃあ、超簡単便利お気楽スクリプトを使う意味なんて、ない訳ですよ。
それこそ、アセンブラ書いとけよ、って話ですよ。
バカでも出来ることを、エレガントにやってこその、プログラミングって云うもんでしょ?
で、見出しになる訳ですわ。
煙草をふかしながら、RailsによるアジャイルWebアプリケーション開発 第2版を眺めていたら、314ページ辺りで、この見出しですよ。
「うわああああっ」って、声上げたよwww
んで、こんな感じに変わりました。
class User < ActiveRecord::Base has_many :asked_friendships, :foreign_key => 'asked_user_id', :class_name => 'Friend', :dependent => :destroy do def with_state(state) find(:all, :conditions => { :state => state }) end end has_many :was_invited_friendships, :foreign_key => 'was_invited_user_id', :class_name =>'Friend', :dependent => :destroy do def with_state(state) find(:all, :conditions => { :state => state }) end end has_many :asked_friends, :through => :asked_friendships, :source => :asked_to has_many :was_invited_friends, :through => :was_invited_friendships, :source => :was_invited_from end
これで、わざわざ自前でコレクション作らなくても、なんやかんやと持ってこれるようになりました。
>> @user.asked_friends
で、該当するUserオブジェクト、
>> @user.asked_friendships
で、該当するFriendオブジェクトを。
>> @user.asked_friendships.with_state("accepted")
で、該当するstateがacceptedなFriendオブジェクトをゲット出来ますな。
...あ〜あ。
俺、超涙目www
打ち拉がれました、なあ...
歳をとる、って云うことは、こういうことなんだな...
キャッシュされているものが、無駄足を踏む結果を生んだり、全く役に立たなかったりなんかする時の、この、無力感ったら、ありゃあしませんよwww
悲しいねwww