Skip to content

Instantly share code, notes, and snippets.

@kennyj
Forked from ryanb/rails_3_1_rc4_changes.md
Created May 6, 2011 17:34
Show Gist options
  • Save kennyj/959393 to your computer and use it in GitHub Desktop.
Save kennyj/959393 to your computer and use it in GitHub Desktop.
Rails 3.1 RC4の変更点(和訳)

Railties 3.1 Beta 1

  • アプリケーションジェネレータの -j オプションは任意の文字列を受け付ける。"foo" が渡されれば、Gemfileに "foo-rails" gemが追加され、アプリケーションのJavaScriptマニフェストは、"foo" と "foo_ujs" を要求する。現在 "prototype-rails" と "jquery-rails" があり、assetパイプラインを経てファイルは提供される。デフォルトは"jquery"。

  • jQueryは、もはやvendoredではなくjquery-rails(gem)によって提供される。

  • PrototypeとScriptaculousは、もはやvendoredではなくprototype-rails(gem)によって提供される。

  • もしSassが利用出来るなら、scaffoldコントローラはSCSSファイルを生成するだろう。

  • コントローラとリソースジェネレータは、自動的にassetスタブを生成するだろう(--skip-assetsでオフにできる)。(もし利用出来るなら)スタブはCoffeeとSassを利用する。

  • jQueryが新しいデフォルトのJavaScriptライブラリ。

  • scaffoldとappジェネレータはRuby1.9においては、Ruby1.9スタイルのハッシュで生成する。

例えば次のような場合:

redirect_to users_path, :notice => "User has been created"

次の様に生成される:

redirect_to users_path, notice: "User has been created"

--old-style-hashオプションで、Ruby1.9においても古いスタイルで生成できる。

  • scaffold_controllerジェネレータをXMLの代わりにJSONのフォーマットブロックを生成するように変更した。

  • minitestで実行される時は、test_help.rbに自然言語テストケース名を追加(Ruby 1.9.2+)

  • コンソールへ結果をインラインで表示する為、ActiveRecordのログ出力を直接標準出力にした。

  • Rack::SSLミドルウェアをロードし、config.force_sslを追加した。全てのリクエストを強制的にHTTPSプロトコルにする。

  • テストの為、gemspecとtestsとdummyアプリケーションと共にpluginを生成する、rails plugin newコマンドを追加した。

  • オプションとしてjquery/prototypeを伴った-jパラメータを追加した。rails new myapp -j jqueryでjQueryアプリを作成できる。デフォルトはまだPrototype。

  • デフォルトのミドルウェアスタックに、Rack::EtagとRack::ConditionalGetを追加した。

  • デフォルトのミドルウェアスタックに、Rack::Cacheを追加した。

  • Engineは、Rackアプリケーションである。

  • Engineに、ミドルウェアスタックを追加した。

  • Engineは、プラグインをロードできる。

  • Engineは、自身のenvironmentファイルをロードできる。

  • 逆にアプリケーションから、Engineのルートヘルパーを呼び出すためのヘルパーを追加した。

  • アプリケーションのdb/migrateディレクトリにpluginsとenginesのマイグレーションをコピーするためのタスク。

  • 複数のディレクトリを操作できるように、ActionDispatch::Staticを変更した。

  • 分離したEngineとしてセットする為、Engineにisolate_namespace()メソッドを追加した。

  • アプリケーションにプラグインと共有Engineから全てのヘルパーを含める。

Action Pack 3.1 Beta 1

  • 例外画面に、標準のENVメソッドをダンプするのみにした(rackのくず(?)全てでは無く)

  • auto_linkが置き換え方法無しに削除された。もし必要ならrails_autolink gem: http://github.com/tenderlove/rails_autolink をインスールする事で利用可能。

  • streamingサポートを追加。

class PostsController < ActionController::Base
  stream :only => :index
end

より詳細情報はActionController::Streamingのドキュメントを読んで。

  • acceptヘッダを無視するためにActionDispatch::Request.ignore_accept_headerを追加し、パラメータとして与えられているフォーマットを考慮するのみ。

  • ActionView::Rendererが作成され、ActionView::ContextにAPIを仕様にした。より詳細情報はそれぞれのオブジェクトをチェックせよ。

  • パラメータをネストしたハッシュにラップする為に、ActionController::ParamsWrapper`を追加した。デフォルトで新しいアプリケーションにおけるJSONリクエストの為になっているだろう(?)

これはconfig/initializer/wrap_parameters.rbActionController::Base.wrap_parametersを設定することにより、カスタマイズできる。

例えば、このルーティングなら

map '*pages' => 'pages#show'

'/foo/bar.json'をリクエストする事によってルーティングできる。params[:pages]は、JSONフォーマットで、"foo/bar"と等しいだろう。もし古い3.0.xの振る舞いへ戻したいなら、:format => falseを渡すことで実現できる。

map '*pages' => 'pages#show', :format => false
  • 単一のクラスメソッド呼び出しで、ベーシック認証を設定できるBase.http_basic_authenticate_withを追加。
class PostsController < ApplicationController
  USER_NAME, PASSWORD = "dhh", "secret"

  before_filter :authenticate, :except => [ :index ]

  def index
    render :text => "Everyone can see me!"
  end

  def edit
    render :text => "I'm only accessible if you know the password"
  end

  private
    def authenticate
      authenticate_or_request_with_http_basic do |user_name, password|
        user_name == USER_NAME && password == PASSWORD
      end
    end
end

..下記のように記述できる。

class PostsController < ApplicationController
  http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index

  def index
    render :text => "Everyone can see me!"
  end

  def edit
    render :text => "I'm only accessible if you know the password"
  end
end
  • 特定のアクションにhttpsプロトコルを強制する為にforce_sslの追加を許す。:onlyやら:exceptも使える。

  • FormHelper#form_forで、:methodを直接指定できるようにする。

form_for(@post, remote: true, html: { method: :delete }) の代わりに form_for(@post, remote: true, method: :delete)
  • JavaScriptHelper#escape_javascript()のエイリアスをJavaScriptHelper#j()にする。 JavaScriptHelperを利用する時、JSON gemが追加するObject#j()メソッドに取って代わる。

  • (config.filter_parametersで指定された)機密なクエリー文字列パラメータは、ログファイルにおいてリクエストパスからフィルターされるだろう。 (訳注 logに出力されるurl変数もフィルターするよという意味でしょう。 https://github.com/rails/rails/commit/68802d0fbe9d20ef8c5f6626d4b3279bd3a42d3e)

  • (↓で削除されていた)to_paramがfalseを返すURLパラメータは、クエリー文字列に現れる。

  • to_paramがnilを返すURLパラメータは、クエリー文字列から削除された。

  • ActionDispatch::MiddlewareStackは継承より(?)コンポジションを使う。It is no longer an array which means there may be methods missing that were not tested.

  • カスタマイズの為もしくはトークンを省略する(:authenticity_token => falseを渡す)為に、form_tagに:authenticity_tokenオプションを追加した。

  • HTML5のbutton_tag ヘルパーを追加する。

  • テンプレートルックアップは継承チェーンを逆上りながら探す。

  • テンプレートをキャッシュするかどうか決定する為に、config.action_view.cache_template_loadingを復活した。

  • url_forと名前付きurlヘルパーは、オプションに:subdomainと:domainを受け付ける。

  • リダイレクトルートメソッドは、質問のurlの部分を変えるためだけのオプションのハッシュや、(リダイレクトを再利用する為)callが呼び出せるオブジェクトを許す。(訳注 https://github.com/rails/rails/commit/0bda6f1ec664fcfd1b312492a6419e3d76d5baa7)

  • config.action_controller.include_all_helpersを追加した。デフォルトでActionController::Basehelper :allされ、全てのヘルパーが含まれる。include_all_helpersをfalseに設定すると、application_helperと対応するコントローラのみ(foo_helperはfoo_controllerの様に)に追加する。

  • HTML5のdata-*属性を生成する為の便利イディオムを:dataのハッシュから渡せるように、tagヘルパーに追加した。

tag("div", :data => {:name => 'Stephen', :city_state => %w(Chicago IL)})
# => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />

キーはダッシュ化される。値はstringとsymbolを除いて、JSONエンコードされる。

  • :onceをrenderに追加した。stringかstringの配列のみ渡す事ができ、Railsは、それぞれ毎に一度のみレンダリングできる。(訳注 https://github.com/rails/rails/commit/940b57789fb9166658974c591e68d22ecab29f34)

  • 古いテンプレートハンドラーAPIを廃止した。新しいAPIは単純にcallを呼び出させる事を要求する。

  • :rhtmlと:rxmlは、テンプレートハンドラーとして削除された。

  • ActionDispatch::Response から、middleware stack にetagの責務を移動。

  • rubyの世界を横断する互換性向上の為にRack::Session store APIに依存する(?)。これはRack::Sessionは4引数を許す#get_sessionや、シンプルな#destroyの変わりに#destroy_session要求する、後方非互換性である。 (訳注 https://github.com/rails/rails/commit/50215f9525b6b5e3bfe703724b9f68177ed8565d)

  • file_fieldは自動的に、囲んでいるformに:multipart => trueをセットする。

  • csrf_meta_tagからcsrf_meta_tagsに変更。後方互換性の為、csrf_meta_tagは別名に。

  • デフォルトスタックにRack::Cacheを追加。Railsキャッシュへ委譲するRailsストアを作成。デフォルトではHTTPキャッシングを使う。もし:public => trueで#expires_in、#fresh_when、#staleを使うなら、Rack::Cacheは使われるだろう、一方キャッシュルールはブラウザのみに適用されるだろう。

Active Record 3.1 Beta 1

  • AR#newAR#createAR#update_attributesは全て、属性割り当て時にロールを考慮する為指定される二番目のハッシュを受け取れる。これはActiveModelの新しいmass assignment機能から出来ている:
class Post < ActiveRecord::Base
  attr_accessible :title
  attr_accessible :title, :published_at, :as => :admin
end

Post.new(params[:post], :as => :admin)

同種のAPIであるassign_attributes()が追加された。またattributes=(params, guard)は廃止された。

  • 遅延評価の為、default_scopeにblockやlambdaもしくはcallを呼び出せるオブジェクトをとる事ができる。
default_scope { ... }
default_scope lambda { ... }
default_scope method(:foo)
  • Default scopes are now evaluated at the latest possible moment, to avoid problems where scopes would be created which would implicitly contain the default scope, which would then be impossible to get rid of via Model.unscoped.

Note that this means that if you are inspecting the internal structure of an ActiveRecord::Relation, it will not contain the default scope, though the resulting query will do. You can get a relation containing the default scope by calling ActiveRecord#with_default_scope, though this is not part of the public API.

[Jon Leighton]

  • クラス内でのdefault_scope複数回呼び出しを(スーパークラスが呼び出す時を含め)廃止する。現在の振る舞いはマージする。
class Post < ActiveRecord::Base # Rails 3.1
  default_scope where(:published => true)
  default_scope where(:hidden => false)
  # The default scope is now: where(:published => true, :hidden => false)
end

Rails3.2では、振る舞いが前のscopeを上書きするように変わるだろう。

class Post < ActiveRecord::Base # Rails 3.2
  default_scope where(:published => true)
  default_scope where(:hidden => false)
  # The default scope is now: where(:hidden => false)
end

もしdefault scopeをマージしたかったら、クラスメソッドとしてdefault scopeを定義し、コード共有の為の標準テクニック利用を推奨する。

class Post < ActiveRecord::Base
  def self.default_scope
    where(:published => true).where(:hidden => false)
  end
end
  • PostgreSQLアダプターは8.2以上のバージョンのみサポートする。

  • ConnectionManagementミドルウェアはrackボディがflushされた後でコネクションプールをクリアするように変更された。

  • ActiveRecordにupdate_columnメソッドを追加した。これは新しいメソッドがオブジェクトの与えられた属性をvalidationやcallbackをスキップし更新する。"updated_at"の更新を含め、いかなるコールバックも実行したくないなら#update_attributeの利用を推奨する。新しいレコードには使うべきではない。

例:

User.first.update_column(:name, "sebastian")         # => true
  • Associations with a :through option can now use any association as the through or source association, including other associations which have a :through option and has_and_belongs_to_many associations [Jon Leighton]

  • 現在のデータベース設定は、ActiveRecord::Base.connection_configでアクセスできる。

  • limitとoffsetの両方を呼び出しているので無ければ、COUNTクエリーからlimitとoffsetを削除する。例えば:

People.limit(1).count           # => 'SELECT COUNT(*) FROM people'
People.offset(1).count          # => 'SELECT COUNT(*) FROM people'
People.limit(1).offset(1).count # => 'SELECT COUNT(*) FROM people LIMIT 1 OFFSET 1'

[lighthouse #6262]

  • ActiveRecord::Associations::AssociationProxy has been split. There is now an Association class (and subclasses) which are responsible for operating on associations, and then a separate, thin wrapper called CollectionProxy, which proxies collection associations.

This prevents namespace pollution, separates concerns, and will allow further refactorings.

Singular associations (has_one, belongs_to) no longer have a proxy at all. They simply return the associated record or nil. This means that you should not use undocumented methods such as bob.mother.create - use bob.create_mother instead.

[Jon Leighton]

  • レコードをbuildしsaveした時に、has_many :through 関連は正しく動くようにする。これはあなたにjoinモデル上のsourceリフレクションに:inverse_ofオプションをセットする事を要求する。
class Post < ActiveRecord::Base
  has_many :taggings
  has_many :tags, :through => :taggings
end

class Tagging < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag, :inverse_of => :tagging # :inverse_of must be set!
end

class Tag < ActiveRecord::Base
  has_many :taggings
  has_many :posts, :through => :taggings
end

post = Post.first
tag = post.tags.build :name => "ruby"
tag.save # will save a Taggable linking to the post
  • has_many :throughアソシエーションに:dependentオプションをサポートした。歴史的かつ実践的名理由で、(通常のhas_manyにとってのデフォルト戦略が:nullifyである事実にも関わらず):delete_allassociation.delete(*records)によって使用されるデフォルト削除戦略である。また、これはソースリフレクションが、belongs_to`である場合のみ動作する。他のシチュエーションでは、throughアソシエーションを直接変更すべきである。

  • Changed the behavior of association.destroy for has_and_belongs_to_many and has_many :through. From now on, 'destroy' or 'delete' on an association will be taken to mean 'get rid of the link', not (necessarily) 'get rid of the associated records'.

Previously, has_and_belongs_to_many.destroy(*records) would destroy the records themselves. It would not delete any records in the join table. Now, it deletes the records in the join table.

Previously, has_many_through.destroy(*records) would destroy the records themselves, and the records in the join table. [Note: This has not always been the case; previous version of Rails only deleted the records themselves.] Now, it destroys only the records in the join table.

Note that this change is backwards-incompatible to an extent, but there is unfortunately no way to 'deprecate' it before changing it. The change is being made in order to have consistency as to the meaning of 'destroy' or 'delete' across the different types of associations.

If you wish to destroy the records themselves, you can do records.association.each(&:destroy)

[Jon Leighton]

  • 一つのALTER文で全ての変更を行う為に、change_tableメソッドに:bulk => trueオプションを追加。

例:

change_table(:users, :bulk => true) do |t|
  t.string :company_name
  t.change :birthdate, :datetime
end

これは下記の用に動くだろう:

ALTER TABLE `users` ADD COLUMN `company_name` varchar(255), CHANGE `updated_at` `updated_at` datetime DEFAULT NULL
  • has_and_belongs_to_manyサポートをやめる。2006年4月に廃止される振る舞いとしてドキュメントかされている。代わりにhas_many :throughを使ってくれ。

  • has_one と belongs_to 関連に create_association! メソッドを追加。

  • モデルとXXXによりジェネレートされたマイグレーションファイルは、古いupdownメソッドの代わりにマイグレーションの(reversibleな)changeメソッドを使う。

  • アソシエーション上の補完SQLコンディション文字列のサポートをやめた。変わりにprocを使え。

前:

has_many :things, :conditions => 'foo = #{bar}'

後:

has_many :things, :conditions => proc { "foo = #{bar}" }

procの中では、eagerローディングではない場合は、'self'はアソシエーションのオーナーオブジェクトである。eagerローディングの場合は'self'はアソシエーションが入っているクラスである(?)

procの中で”通常”のコンディションも書けるので、次のコードも動く:

has_many :things, :conditions => proc { ["foo = ?", bar] }

以前has_and_belongs_to_manyアソシエーションに:insert_sqlと:delete_sqlは、登録されたり削除されたりするレコードを得るため、'record'を呼び出す事を許していた。これはprocへの引数として渡される。

  • BCryptとソルトを利用した簡単なパスワードを利用する為、(ActiveModel::SecurePasswordを経て) ActiveRecord::Base#has_secure_password を追加した。例:
# Schema: User(name:string, password_digest:string, password_salt:string)
class User < ActiveRecord::Base
  has_secure_password
end

user = User.new(:name => "david", :password => "", :password_confirmation => "nomatch")
user.save                                                      # => false, password required
user.password = "mUc3m00RsqyRe"
user.save                                                      # => false, confirmation doesn't match
user.password_confirmation = "mUc3m00RsqyRe"
user.save                                                      # => true
user.authenticate("notright")                                  # => false
user.authenticate("mUc3m00RsqyRe")                             # => user
User.find_by_name("david").try(:authenticate, "notright")      # => nil
User.find_by_name("david").try(:authenticate, "mUc3m00RsqyRe") # => user
  • modelをジェネレートする時、belongs_toやreferencesカラムの為にデフォルトでadd_indexを追加する。
rails g model post user:belongs_to は下記を生成するだろう:
class CreatePosts < ActiveRecord::Migration
  def up
    create_table :posts do |t|
      t.belongs_to :user

      t.timestamps
    end

    add_index :posts, :user_id
  end

  def down
    drop_table :posts
  end
end
  • belongs_toオブジェクトのidをセットすると、そのオブジェクトへの参照も更新するだろう。

  • ActiveRecord::Base#dupとActiveRecord::Base#cloneのセマンティクスは通常のRubyのdupとcloneのセマンティクスに近づけられた。

  • ActiveRecord::Base#cloneを呼び出す事は、レコードの浅いコピーの結果になり、frozen状態がこぴーされる(?)。コールバックは呼ばれない。

  • ActiveRecord::Base#dupを呼び出す事は、レコードを複製しafter_initializeフックを呼び出す。fronzen状態がコピーされない。全てのアソシエーションがクリアされる。dupされたレコードはnew_record?でtrueを返し、idはnilでsave可能である。

  • マイグレーションは、リバーシブルとして定義されている。そしてそれはマイグレーションシステムが、あなたのマイグレーションをどのように逆転するか示す事を意味する。リバーシブルなマイグレーションを使うためには、"change"メソッドを定義しなければいけない。例えば:

class MyMigration < ActiveRecord::Migration
  def change
    create_table(:horses) do
      t.column :content, :text
      t.column :remind_at, :datetime
    end
  end
end

自動的に反転できない場合がある。そのような場合は'up'と'down'を定義すべきである。もしchangeが反転できない場合は、IrreversibleMigration例外がdown時に発生するだろう。

  • マイグレーションはクラスメソッドより、インスタンスメソッドを使うべきである:
class FooMigration < ActiveRecord::Migration
  def up
    ...
  end
end
  • has_oneは一つのafter_saveの代わりに、分離されたafter_create / after_updateでアソシエーションを維持する。

  • 次のコード:

Model.limit(10).scoping { Model.count }

は次のSQLを生成する:

SELECT COUNT(*) FROM models LIMIT 10

望んでいる事と違う場合次の様にできる:

Model.limit(10).scoping { Model.all.size }

Active Model 3.1 Beta 1

  • attr_accessibleとその仲間たちは、ロールを指定する為、:asオプションを受け付ける。

  • InclusionValidator、ExclusionValidator、FormatValidatorへのオプションとして、procかlambdaを渡せるようにした。

引数として現在のレコードを受け取り、callメソッドを呼び出せる、Proc(やlambda)を渡せるようになった。Proc(やlambda)は、InclusionValidatorとExclusionValidatorでは#include?を呼び出せるオブジェクトを返す必要があり、FormatValidatorでは正規表現を返す必要がある。

  • BCryptとソルトを利用した簡単なパスワードを利用する為、ActiveModel::SecurePasswordを追加した。

  • ActiveModel::AttributeMethodsは、必要な時に定義される属性を許す。

Active Support 3.1 Beta 1

  • stringをStringInquirerオブジェクトに変更する為の便利メソッドとして、String#inquiryを追加した。

  • オブジェクトが他のオブジェクトに含まれているかどうかテストする為にObject#in?を追加した。

  • LocalCacheストラテジーは、?(posing for pictures)の無名クラスでは無く、本当のミドルウェアクラスである。

  • 再読込可能クラスへの参照を保持する為、ActiveSupport::Dependencies::ClassCacheを追加した。

  • ClassCacheの直接の利点を得る為、ActiveSupport::Dependencies::Referenceをリファクタリングした。

  • Ruby 1.8で、Range#include?へのエイリアスとしてRange#cover?をバックポートした。

  • Date/DateTime/Timeにweeks_agoprev_weekを追加した。

  • ActiveSupport::Dependencies.remove_unloadable_constants!に、before_remove_constコールバックを追加した。

Action Mailer 3.1 Beta 1

  • 変更なし。

Active Resource 3.1 Beta 1

  • 変更なし。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment