新しいブログに移転しました。独自ドメインだけど見ての通りtumblrでございます。理由はこのへんとか参照頂けると幸いです。
このブログについては、記事を少しずつ移しながら、最終的には廃止してポートフォリオ的なサイトに切り替えたいと目論んでおります。個別記事のリダイレクトはしないつもりなのでそれは本当に申し訳ございませんです。
何度か紹介してるCakePHP向けcakephp-pjax-pluginについて、やっとCakePHP2.0対応させたのでお知らせ。ついでにCakePHP2.0の命名規約に従い、名前をCamelCaseに変えて、CakePjaxというプロジェクトにしました。DEMOはこちら。
今は仕事で使いたいもの、かつ実装が容易なものから優先的に作っているんですが、今後はもう少し大きなもの、CakeだけじゃなくPHP全般の役に立つものが作りたいなと思います。
CakePHP2.0でApp::importの代替として追加されたApp::usesで起きた勘違い。
// 使い方
App::uses('クラス名', 'パッケージ名');
// 間違い
App::uses('AuthComponent', 'Controller¥Component');
// 正しくは
App::uses('AuthComponent', 'Controller/Component');
Grahamさんのプレゼンでも名前空間ぽいみたいなこと言ってたしPSR-0の話もしてたから、てっきりパッケージはバックスラッシュ区切りかと思った。
この件についてTipshareにも投稿してみたので良かったらどうぞ。
CakePHP2.0のApp::usesの使い方 | tipshare.info
すごく違和感のある挙動に遭遇したのでメモ。
例えば、以下のようなhas_manyな関係を持つ2つのクラスがある。
class Parent < ActiveRecord::Base has_many :children accepts_nested_attributes_for :children end class Child < ActiveRecord::Base belongs_to :parent end
Formからネストしたパラメータが渡ってきた場合など、以下のようにする場合が多いと思う。
親データ1件と、その子データ3件を同時に作成する場合。
この場合、p.children.empty?はtrueを返すが、実際にp.childrenを出力すると、期待通りChildクラスのインスタンスが3つ入っている。
しかも、p.childrenを一度出力した後に再度p.children.empty?を呼ぶとfalseが帰ってくるという不思議仕様。
p = Parent.new({
name: 'parent',
children: [
{ name: 'child1' },
{ name: 'child2' },
{ name: 'child3' },
]
})
p.children.empty?
=> true
p.children
=>[#<Child name:'child1'>,#<Child name:'child2'>,#<Child name:'child3'>]
p.children.empty?
=> false
ちなみに、上記とデータ構造は全く同じだが、一度Parentのインスタンスを作成してから、Childを1つずつ追加していくと、p.children.empty?はきちんとfalseを返し、p.childrenの出力も期待通りChildクラスのインスタンスが3つ入っている。
p = Parent.new({ name: 'parent' })
p.children << Child.new({ name: 'child1' })
p.children << Child.new({ name: 'child2' })
p.children << Child.new({ name: 'child3' })
p.children.empty?
=> false
p.children
=>[#<Child name:'child1'>,#<Child name:'child2'>,#<Child name:'child3'>]
これってlazy loading的な何かがあるので仕方ないですよとか言われたら納得しちゃうかもしれないけど単純にバグな気がするのでちょっと頑張る
Rails3時代の認証システムはRestful Authenticationからdeviseに変わったみたいですが、このdeviseという認証システムには以下のような非常に豊富な機能が付いており、殆どのアプリケーションに対してオーバースペックな気がします。
とはいえ、わざわざDeviseのControllerをオーバーライドして不要なアクションを削除したりするのはとてもメンドクサイので、Routingを編集することで当該機能にアクセスできないようにしちゃます。
deviseのroutesを定義しているdevise_forメソッドは、resourcesに使うような標準オプションも受け入れてくれるので以下のようにすればOKです。
# RAILS_ROOT/config/routes.rb # デフォルトはこんな感じ devise_for :users # 全部無効化 devise_for :users, only: :none # ログイン、ログアウトだけ有効化 devise_for :users, only: [:sign_in, :sign_out, :session] # 小さいアプリではこんな感じで使ってます devise_for :users, only: [:session] do get '/sign_in', :to => 'devise/sessions#new', :as => :new_user_session get '/sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session end
RailsもDeviseも非常に大きなシロモノになっていて、ちょっとしたアプリを作るには面倒なことが増えてきたので最近はPadrinoを勉強してます。すごくいいのでぜひどうぞ。