過去14か月間のRuby on Railsフレームワークの開発の概要

時間が経つにつれて、時間がない。 周囲はすべて非常に急速に発展しています。 ある時点で、Ruby on Railsの最新バージョンを使用していますが、実装されている「機能」の多くを使用していないことに気付きました。

過去14か月間にRailsに導入されたものを振り返ります。 各イノベーションには小さな例が付随しますが、それぞれのそのような説明は多数の個別の記事またはリンクのトピックであるため、記事の基になっているソースからそのままコピーします。



ストーリーは次の形式になります。

バージョン

彼女の後に何が起こった

新しいバージョンには、上記のすべての革新が含まれています。

バージョン2.0.2。 2007年12月



レールは、1.xxシリーズと比較して単純にレベルアップしました。 どうしたの?

キャッシング用のエンジンを指定する機会があります:

Copy Source | Copy HTML<br/> ActionController::Base .cache_store = :memory_store<br/> ActionController::Base .cache_store = :file_store, "/path/to/cache/directory" <br/> ActionController::Base .cache_store = :drb_store, "druby://localhost:9192" <br/> ActionController::Base .cache_store = :mem_cache_store, "localhost" <br/>





自分で作る機会もあります

タイムゾーンの簡素化された作業

Copy Source | Copy HTML<br/> # Set the local time zone <br/> Time .zone = "Pacific Time (US & Canada)" <br/> <br/> # All times will now reflect the local time <br/>article = Article.find(:first)<br/>article.published_at #=> Wed, 30 Jan 2008 2:21:09 PST -08:00 <br/> <br/> # Setting new times in UTC will also be reflected in local time <br/>article.published_at = Time .utc( 2008 , 1 , 1 , 0 )<br/>article.published_at #=> Mon, 31 Dec 2007 16 : 00 : 00 PST - 08 : 00 <br/>







Named_scopeが登場しました:

Copy Source | Copy HTML<br/> class User < ActiveRecord::Base<br/> named_scope :active, :conditions => {:active => true }<br/> named_scope :inactive, :conditions => {:active => false }<br/> named_scope :recent, lambda { { :conditions => [ 'created_at > ?' , 1 .week.ago] } }<br/>end<br/> <br/># Standard usage<br/> User .active # same as User . find (:all, :conditions => {:active => true })<br/> User .inactive # same as User . find (:all, :conditions => {:active => false })<br/> User .recent # same as User . find (:all, :conditions => [ 'created_at > ?' , 1 .week.ago])<br/> <br/># They 're nest-able too! <br/> User.active.recent <br/> # same as: <br/> # User.with_scope(:conditions => {:active => true}) do <br/> # User.find(:all, :conditions => [' created_at > ?', 1 .week.ago])<br/> # end <br/>





has_one継承には、次のオプションがあります。

Copy Source | Copy HTML<br/> class Magazine < ActiveRecord::Base<br/> has_many :subscriptions<br/> end <br/> <br/> class Subscription < ActiveRecord::Base<br/> belongs_to :magazine<br/> belongs_to : user <br/> end <br/> <br/> class User < ActiveRecord::Base<br/> has_many :subscriptions<br/> has_one :magazine, :through => : subscriptions, :conditions => [ 'subscriptions.active = ?' , true ]<br/> end <br/>





「ダーティオブジェクト」の導入:

Copy Source | Copy HTML<br/>article = Article.find(: first )<br/>article.changed? #=> false <br/> <br/># Track changes to individual attributes with <br/># attr_name_changed? accessor<br/>article.title #=> "Title"<br/>article.title = " New Title"<br/>article.title_changed? #=> true <br/> <br/># Access previous value with attr_name_was accessor<br/>article.title_was #=> "Title"<br/> <br/># See both previous and current value with attr_name_change accessor<br/>article.title_change #=> ["Title", " New Title"] <br/>





変更されたフィールドのみをデータベースに送信するようなSQLクエリを生成できるようになった理由:

Copy Source | Copy HTML<br/>article = Article.find(: first )<br/>article.title #=> "Title"<br/>article.subject #=> "Edge Rails"<br/> <br/># Update one of the attributes<br/>article.title = " New Title"<br/> <br/># And only that updated attribute is persisted to the db<br/>article. save <br/> #=> " UPDATE articles SET title = 'New Title' WHERE id = 1" <br/>





これで、Railsアプリケーションが依存するgemとバージョンを指定できます。

Copy Source | Copy HTML<br/>Rails::Initializer.run do |config| <br/> <br/> # Require the latest version of haml<br/> config.gem "haml"<br/> <br/> # Require a specific version of chronic<br/> config.gem "chronic", :version => '0.2.3' <br/> <br/> # Require a gem from a non-standard repo<br/> config.gem "hpricot", :source => "http://code.whytheluckystiff.net"<br/> <br/> # Require a gem that needs to require a file different than the gem 's name <br/> # Ie if you normally load the gem with require ' aws/s3 ' instead of <br/> # require ' aws-s3' then you would need to specify the :lib option <br/> config.gem "aws-s3", :lib => "aws/s3" <br/> end <br/>





ほぼ同時に、Rails開発者はxxx_nameタイプの移行に伴うhemoについて忘れなければなりませんでした。 命名移行はUTCベースになりました:

Copy Source | Copy HTML<br/>> script/generate migration one<br/> create db/migrate/20080402122512_one.rb <br/>





バージョン2.1。 2008年6月



パーシャルの名前は自動的に決定され始めました:

Copy Source | Copy HTML<br/>render :partial => 'employees' , :collection => @workers, :as => :person <br/>





validates_length_ofを検証するために、オプションが追加されました:tokenizer:

Copy Source | Copy HTML<br/>validates_length_of :article, :minimum => 10 ,<br/> :too_short => "Your article must be at least %d words in length." ,<br/> :tokenizer => lambda {|str| str.scan(/\w+/) } <br/>





モデルを検索する方法のオプション:結合では、文字列だけでなく、SQLのすべての規則を観察するだけでなく、モデルの名前だけを指定できます。

Copy Source | Copy HTML<br/> class Article < ActiveRecord::Base <br/> belongs_to :user<br/> end <br/> <br/> class User < ActiveRecord::Base <br/> has_many :articles<br/> end <br/> <br/> # Get all the users that have published articles <br/> User .find(:all, :joins => :article,<br/> :conditions => [ "articles.published = ?" , true ]) <br/>





また、オプション:条件をより詳細に説明できます。

Copy Source | Copy HTML<br/> # Get all the users that have published articles <br/>User.find(:all, :joins => :article, :conditions => { :articles => { :published => true } }) <br/>





メモ化が現れたため、|| =を忘れることができましたが、私は個人的にどうにかしてまだ定着していません。

Copy Source | Copy HTML<br/> class Person < ActiveRecord::Base <br/> <br/> def social_security <br/> decrypt_social_security<br/> end <br/> <br/> # Memoize the result of the social_security method after <br/> # its first evaluation (must be placed after the target <br/> # method definition). <br/> # <br/> # Can pass in multiple symbols: <br/> # memoize :social_security, :credit_card <br/> memoize : social_security <br/> ...<br/> end <br/> <br/>@person = Person .new<br/>@person. social_security # decrypt_social_security is invoked <br/>@person. social_security # decrypt_social_security is NOT invoked <br/>





「ネストされたモデルの質量割り当て」と呼ばれるものが表示されます(これをどのように変換しますか?)。一般に、例の後、すべてが明確になります。

Copy Source | Copy HTML<br/> class User < ActiveRecord::Base <br/> validates_presence_of :login<br/> has_many : phone_numbers <br/> end <br/> <br/> class PhoneNumber < ActiveRecord::Base <br/> validates_presence_of :area_code, :number<br/> belongs_to :user<br/> end <br/> class User < ActiveRecord::Base <br/> validates_presence_of :login<br/> has_many : phone_numbers , :accessible => true <br/> end <br/> <br/>ryan = User .create( {<br/> :login => 'ryan' ,<br/> : phone_numbers => [<br/> { :area_code => '919' , :number => '123-4567' },<br/> { :area_code => '920' , :number => '123-8901' }<br/> ]<br/>})<br/> <br/>ryan. phone_numbers .count #=> 2 <br/> <br/> # one more way <br/> class User < ActiveRecord::Base <br/> <br/> ...<br/> <br/> def phone_numbers =(attrs_array)<br/> attrs_array.each do |attrs|<br/> phone_numbers .create(attrs)<br/> end <br/> end <br/> <br/> end <br/>





パフォーマンスを忘れないでください:

Copy Source | Copy HTML<br/> <% form_for @user do |f| %> <br/> <% = f.text_field :login %> <br/> <% fields_for :phone_numbers do |pn_f| %> <br/> <% = pn_f.text_field :area_code %> <br/> <% = pn_f.text_field :number %> <br/> <% end %> <br/> <% = submit_tag %> <br/> <% end %> <br/>





したがって、すべてのロジックをモデルに含めることができ、コントローラーは次のようになります。

Copy Source | Copy HTML<br/>class UserController < ApplicationController<br/> <br/> # Create a new user and their phone numbers with mass assignment<br/> def new<br/> @user = User.create(params[:user])<br/> respond_to do |wants|<br/> ...<br/> end<br/> end<br/>end <br/>





すべてのオブジェクトにはメタクラスメソッドがあります。 wtf



ほぼ同時期に、「標準国際化フレームワーク」が誕生しました。見落としておらず、現在プロジェクトで使用している人はいないと思います。

Etagが登場しました。これにより、サーバー側とクライアントの両方でキャッシュを使用して(後続の変更に基づいて)非常に適切に管理できます。 詳細については、 すばらしいスクリーンキャスト記事をお送りください

named_scope evolved 、簡単な例:

Copy Source | Copy HTML<br/>class Article < ActiveRecord::Base<br/> <br/> # Only get the first X results<br/> named_scope :limited, lambda { |num| { :limit = > num } }<br/> <br/>end<br/> <br/># Get the first 5 articles - instead of Article.find(:all, :limit = > 5)<br/>Article.limited(5) #= > [ < Article id: ... > , < .. > ] <br/>





浅いルートが現れました 。 それ以降のバージョンでは、このオプションはネストされたルートに影響を与えなくなっていることに注意してください。

一方、Google Summer of Codeプログラムのおかげで、誰かJoshua PeakがRailsをスレッドセーフにしました。 これが完了するとすぐに、Ruby on Railsはデータベース接続のプールを取得しました。

バージョン2.2.2 2008年10月



2つのルートがルートに表示されました。IMHO、オプションはそれほど悪くありません:を除いて:のみ。 説明例:

Copy Source | Copy HTML<br/># Only generate the :index route of articles<br/>map.resources :articles, :only = > :index<br/> <br/># Generate all but the destroy route of articles<br/>map.resources :articles, :except = > :destroy<br/> <br/># Only generate the non-modifying routes of articles<br/>map.resources :articles, :only = > [:index, :show] <br/>





named_scope-default_scopeに拡張を追加しました:

Copy Source | Copy HTML<br/>class Article < ActiveRecord::Base<br/> default_scope :order = > 'created_at DESC'<br/> named_scope :published, :conditions = > { :published = > true }<br/>end<br/>Article.find(:all) #= > "SELECT * FROM `articles` ORDER BY created_at DESC"<br/>Article.published #= > "SELECT * FROM `articles` WHERE published = true ORDER BY created_at DESC" <br/>





application.rbの名前をapplication_controller.rbに変更することが決定されました。これはRails 2.3以降で有効になります。

パーシャルはさらに進化しました

Copy Source | Copy HTML<br/>render :partial = > 'articles/article', :locals = > { :article = > @article }<br/># Render the 'article' partial with an article local variable<br/>render 'articles/article', :article = > @article<br/> <br/># Or even better (same as above)<br/>render @article<br/> <br/># And for collections, same as:<br/># render :partial = > 'articles/article', :collection = > @articles<br/>render @articles <br/>





Object.tryが登場しました:

Copy Source | Copy HTML<br/># No exceptions when receiver is nil<br/>nil.try(:destroy) #= > nil<br/> <br/># Useful when chaining potential nil items<br/>User.admins.first.try(:address).try(:reset) <br/>





末尾に.formatが付いているルートは削除されます。 やった! 個人的に、私はそれらをほとんど必要としませんでした。 今すぐ.formatを使用する方法の例:

Copy Source | Copy HTML<br/>formatted_article_path(article, :xml) = > article_path(article, :format = > :xml)<br/>formatted_new_article_path(:json) = > new_article_path(:format = > :json)<br/> <br/>





2008年12月に、テンプレートに基づいてアプリケーションを生成する機能が追加されました。 詳細。

少し後に、Rails Metalが表示されます。これにより、MVCモデルをバイパスして、クライアントに回答を与えることができます。 主題のスクリーンキャスト

named_scopeは動的になります:

Copy Source | Copy HTML<br/>Article.find_by_published_and_user_id(true, 1)<br/> #= > "SELECT * FROM articles WHERE published = 1 AND user_id = 1"<br/>Article.scoped_by_published_and_user_id(true, 1).find(:all, :limit = > 5)<br/> #= > "SELECT * FROM articles WHERE published = 1 AND user_id = 1 LIMIT 5"<br/>Article.scoped_by_published(true).scoped_by_user_id(1)<br/> #= > "SELECT * FROM articles WHERE published = 1 AND user_id = 1 <br/>





新年の後、 HTTPダイジェスト認証が表示されます

ネストされたモデルの質量割り当てに続いて、ネストされたオブジェクトフォームが表示されます。 素晴らしい革新。

バージョン2.3.0RC1。 2009年2月



RoRの最新のイノベーションは、バッチ検索です。 すぐに例:

Copy Source | Copy HTML<br/>Article.each { |a| ... } # = > iterate over all articles, in chunks of 1000 (the default)<br/>Article.each(:conditions = > { :published = > true }, :batch_size = > 100 ) { |a| ... }<br/> # iterate over published articles in chunks of 100<br/>Article.find_in_batches { |articles| articles.each { |a| ... } }<br/> # = > articles is array of size 1000<br/>Article.find_in_batches(:batch_size = > 100 ) { |articles| articles.each { |a| ... } }<br/> # iterate over all articles in chunks of 100<br/>class Article < ActiveRecord::Base<br/> named_scope :published, :conditions = > { :published = > true }<br/>end<br/> <br/>Article.published.find_in_batches(:batch_size = > 100 ) { |articles| ... }<br/> # iterate over published articles in chunks of 100 <br/>





バージョン2.3.0。 ?、2009



私たちはあなたを待っていません。



開発者の注意を引きます。 プロジェクトにあるRoRのバージョンを最大限に使用し、車輪を再発明しないでください:)幸運と良い一日。 コメントと修正を歓迎します。




All Articles