第28回 Rails勉強会@東北に参加

https://www.facebook.com/events/378705102216002/

OzakiさんによるRails4.0ネタでした。
はじめにこちらのスライド。
https://speakerdeck.com/alindeman/rails-4-dot-0-whirlwind-tour

その中から特にStrong ParametersとTurbolinksについては、スライド見終わった後、RailsCastsをネタに皆で手を動かしながらワイワイとやりました。
http://railscasts.com/episodes/371-strong-parameters
http://railscasts.com/episodes/390-turbolinks

Turbolinksはこのままリリースされたらギャッという人がたくさん出そうでだいぶアレ。



後、スライド中で出てきたnoneというメソッドやallがActiveRecord::Relationを返す件について↓

#Relation#none 
# Chainable null object 
> Post.none 
#<ActiveRecord::Relation []> 
# Doesn't hit database > 
Post.none.to_sql 
"" 
> Post.none.to_a 
[]


#Relation#all returns a relation (chainable) 
# Rails 3 
> Post.all.class 
Array
# Rails 4 
> Post.all.class 
ActiveRecord::Relation 
> Post.all.to_a.class
 Array

勉強会中に、jQuery関数型言語っぽくチェーンして書けて、条件分岐を書くケースが減るという事かなとか言いましたが、実際の使用ケースを見ないとわからないという意見がありました。
で、記事に書いてみようかと思ったら、Active Record Query Interface — Ruby on Rails Guidesここに書いてあったのでまるまる引用。

9 Null Relation
The none method returns a chainable relation with no records. Any subsequent conditions chained to the returned relation will continue generating empty relations. This is useful in scenarios where you need a chainable response to a method or a scope that could return zero results.

Post.none # returns an empty Relation and fires no queries.


# The visible_posts method below is expected to return a Relation.
@posts = current_user.visible_posts.where(name: params[:name])
 
def visible_posts
  case role
  when 'Country Manager'
    Post.where(country: country)
  when 'Reviewer'
    Post.published
  when 'Bad User'
    Post.none # => returning [] or nil breaks the caller code in this case
  end
end

Rails4.0では、noneでActiveRecord::Relationを返してくれるので、上記のようにcurrent_user.visible_postsのところで空配列が来てるかの条件分岐を入れずに、jQueryのようにチェーンして書けると。
ScalaのOptionのNoneとかも彷彿とさせますね。

Rails3.2までの場合だと、例えば[]やnilを返してそれをチェックするとか、visible_posts_user_nameといったvisible_postsとwhere(name: params[:name])を一気に処理するメソッドを作成するといったアプローチになるかと。

Rails4.0の場合は、visible_postsメソッドを他でも利用出来て、再利用性を高めて、さらに重複を排除してコードを書けるようになるというのがメリットかなあと。

allがActiveRecord::Relationを返すようになるというのも同様な流れな気が。で、allがActiveRecord::Relation返せば、scopedはいらない子になるのでDEPRECATIONと。
もっともallの場合は、all呼ばないでwhere呼ぶ事が多い気がするので使用ケースは少ないかと。
個人的にはこんな風に理解しました。


参加の皆様お疲れ様でした。

YQLで複数ブログのRSSをJSONで取得して、新着として表示する

前に単独のRSSを取得する方法を書いたけど、複数取得を書くのをすっかりわすれていたので。

前回


簡単なのでYQLだけ。ついでに日付順になるようsortも。

select * from rss where url = 'http://d.hatena.ne.jp/yuichi_katahira/rss' or url='http://blog.livedoor.jp/katahirado/index.rdf' | sort(field="date",descending="true");


なお、RSS2.0を混ぜると、日付はpubDateになり、RSS1.0のdate(dc:date)とは異なるので、YQLの結果だけで日付順にするのは無理かと。
あと、Atom,Feed0.3なんかもまぜようとすると、from句をrssからxmlにしないと当然取れない。
で、XMLにした場合は、取れる結果が、各ブログの記事が要素になったフラットな配列ではなく、各ブログのfeedが要素になった結果が返ってくるので、自前で少し加工する必要がある。

WebViewに動的にJSを読み込みした後の評価(実行)タイミングではまった

11/20日追記:SafariChromeでも試して見たところ、JSでbodyに複数appendChildすると順番は一定しない事を確認。そうだったのか。
http://blog.setunai.net/20120317/javascript%E3%81%AE%E5%AE%9F%E8%A1%8C%E9%A0%86%E5%BA%8F%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/



備忘録。


WebViewは、JSファイルを並列に読み込む。
で、動的に4つくらいJSファイルをbodyの末尾に読み込んでいるが、コードが追加順番に依存しているので、追加した順番に評価してほしいがどうも一定しない。



LABjsRequireJS等を使うのが良いのだろうが、手っ取り早く、Railsライクに全部のJavaScriptファイルを順番に結合したファイルを作成、読み込むことで解決した。


ただこれをやると開発時に面倒くさくなるので、各JSファイルをちょっと手直しして結合する書き捨てスクリプトRubyで書いた。
こういった処理は、GoogleのClosure Compilerや、RailsのAsset Pipelineなどを利用するのが標準的か。
しかし今回の場合は、Objective-C側から呼び出している為JS側では呼び出されていないメソッドや、Objective-C側から動的に挿入されているはずのネームスペースのメソッドをJS側から呼ぶといった、変則的なコードが散らばっていたりするという事情があるので、自前の結合スクリプトを用意した。圧縮も勝手にされるとちと困るので。


参考
http://kawa.at.webry.info/200911/article_7.html

11/20オープンアワー@片平堂告知

11/20にオープンアワーを片平堂オフィスで行います。
久しぶりに開催します。事務所の入っているマンションが、現在震災からの復旧工事でうるさい可能性があります。予めご了承ください。

詳細は以下をご覧ください。お気軽にどうぞ。

                                                                                                                                            • -

オープンアワー@片平堂

                                                                                                                                            • -

・日時
11/20(火) 7:30〜12:00
出入りは自由にどうぞ、参加、退出の時間もご自由に


・場所
片平堂 http://katahirado.jp/about.html
http://maps.google.co.jp/maps?q=%E4%BB%99%E5%8F%B0%E5%B8%82%E9%9D%92%E8%91%89%E5%8C%BA%E6%9C%AC%E7%94%BA1-12-2&hl=ja&ie=UTF8&ll=38.266118,140.879188&spn=0.009822,0.019076&hnear=%E5%AE%AE%E5%9F%8E%E7%9C%8C%E4%BB%99%E5%8F%B0%E5%B8%82%E9%9D%92%E8%91%89%E5%8C%BA%E6%9C%AC%E7%94%BA%EF%BC%91%E4%B8%81%E7%9B%AE%EF%BC%91%EF%BC%92%E2%88%92%EF%BC%92&gl=jp&t=m&z=16&brcurrent=3,0x5f8a2826f0704f57:0x1a70d9b7c411e4c2,0,0x5f8a2826f7863c8b:0xb250301829f18379&layer=c&cbll=38.266095,140.879316&panoid=J1zVp0HV6Q8VdhAdZGdgiA&cbp=12,0,,0,0
入り口は、歯科がある2階にあがる階段と利休が入っているビルの間です。
奥にエレベーターがあります。


・費用
100円/学生の方無料(主に飲み物代、学生の方は学生と分かるものをお持ちください。片平と面識のある方は不要です)


・内容
読書、プログラミングなど各自やりたいことを行う活動です。


・参加方法
ふらっときていただいて構いません。連絡不要です。
連絡しないと気が済まないという方は、メールなりTwitterなりFacebookなりで連絡ください。


・必要な物
ノートPC、書籍など各自必要だと思うものをご持参ください。


・ネットワーク
イーモバイルLTE回線があります


・電源
使用可能です。


・その他
備え付けの飲み物、食べ物は好きなだけどうぞ。
おいてある書籍も自由にお使いください。
http://f.hatena.ne.jp/yuichi_katahira/20110710145316
http://f.hatena.ne.jp/yuichi_katahira/20110710145314
備え付けのハンガーもご自由にどうぞ。
http://f.hatena.ne.jp/yuichi_katahira/20120508065750
飲食持ち込みもOKです。朝食なう、おやつなうも問題ありません。

                                                                                                                                            • -

宜しくお願いします:-)


103

ファイルのアイコンを取得する

一つ前のエントリーでは端折っていたが、ファイルのアイコンを取得するのが目的で、pathをあれこれやってあれってなったのであんなエントリーを残した。

せっかくなのでアイコン取得もメモ。


pathをStringでアイコン取得する場合。

//_fullPath はこんなのが来てる。 @"file://localhost/directory/index.html";
NSString *filePath =		
[[_fullPath stringByReplacingOccurrencesOfString:@"file:/localhost" withString:@""]
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return [[NSWorkspace sharedWorkspace] iconForFile:filePath];

とかやる。前のエントリーのは、このケースでいうとfile://localhostを置換しようとしているのに、実際にはここに渡って来る前の文字列生成処理で、file:/localhostが渡ってきてた&decodeも抜けてたという話。


NSURLでアイコンを取得

//_fullPath はこんなのが来てる。 @"file://localhost/directory/index.html";
NSURL *fileUrl = [NSURL URLWithString:_fullPath];
NSImage *image=nil;
[fileUrl getResourceValue:&image forKey:NSURLEffectiveIconKey error:NULL];
return image;

file:/localhost状態の文字列をNSURLにして、アイコン取得できなくて、StringでもNSURLでもアイコンが取得出来ないなあと調べたら、file:/localhostになっちゃってるじゃないかというのが、前回のエントリの真相でした。

file://localhost/...を使っているのは、アプリがWebViewメインのものなので、このほうが都合がいいため。