約5か月前、私はzendフレームワークに縛られてレールに移動しました。 それから彼は彼のプロジェクト
www.okinfo.ruを書き直し始めました。 これですでに終了し、sloccountはプロジェクトの行数が15000から4000に減少したことを示しました。私の友人のphp開発者はサクセスストーリーを求め、その結果、この記事が誕生しました。 その中で、それがどのようだったかを説明するとともに、ルビーへの私の移行について少し話をします。
背景
www.starlook.ruの主な開発者として約2年間働いた後、私はあなたがそれが先に進む時であると理解するようになりました。 アプリケーションアーキテクチャが落ち着き、スケーリングが定められ、コードが一般的に微調整され、一般に、開発プロセス全体が明確にデバッグされました。 実際、私たちは機能を増やし続け、すでに書かれたものをサポートしました。 この時点で、楽しみのために、ジャンゴとレールを詳しく調べ始めました。 私は言語としてpythonが好きだったという事実にもかかわらず、djangoは感動しませんでした。 そして、レールとルビーでは状況は完全に異なっていました。 これは一目で愛と呼ぶことができます。 文字通り1か月の勉強の後、ルビー開発者の欠員の提案とともに私のサークルに手紙が届きましたが、これは偶然でしたが、 何らかの理由で送信者はルビーを知っていると思った。 一般的に、私はこれが運命だと決め、多くのインタビューを行った後、彼らは私を新しい場所の
ハックに連れて行ってくれました。
なんで?
レールを理解した後、ZFでプロジェクトを書き続けることは非常に困難でした。手でやりすぎて、ほぼすべてのタスク(タグ、ツリー、デプロイ、移行など)について独自の決定を書かなければなりませんでした。 このプロジェクトには余暇があまりないことを考えて、1石で2羽の鳥を殺して、それを書き直すことにしました。 第一に、開発とサポートを簡素化し、第二に、関連するテクノロジーに関する知識を強化することです。
環境設定
rvm.beginrescueend.com -Rubyのいくつかのバージョンのインストールとgemsetのサポート。
en.wikipedia.org/wiki/RubyGems-Gemssudo apt-get install rubygems
gem install rails
rails s
, . .
.
. tail -f log/development.log (http://habrastorage.org/storage/29abc841/af70206c/2794fbe5/5d1f434f.png). , , , , ..
rails c
irb . . .
netbeans vim.
REST
habrahabr.ru/blogs/webdev/38730guides.rubyonrails.org/routing.html, . REST .
:
pastebin.com/x0bA3siH:
namespace :admin do
resources :brands do
resources :systems
end
end
rake routes :
pastebin.com/mPSvzkAJ. :
admin_brand_systems_path(@brand) #
admin_brand_systems_url(@brand) #
. Zend_Controller_Router_Route_Hostname.
, . rails3 , :
# ZF
match "/company/:id" => redirect("/companies/%{id}")
ZF Zend_Rest_Controller Zend_Rest_Route, , :
$restRoute = new Zend_Rest_Route($front, array(), array(
'api',
'backlog' => array('task'),
));
$router->addRoute('rest', $restRoute);
, .
guides.rubyonrails.org/action_controller_overview.html:
pastebin.com/TYhYAWEQ:
pastebin.com/seJzhYMq. ZF, , .
( ) — ApplicationController ( ). . .
(ThinkingSphinx)
.
www.okinfo.ru.
, ,
DSL.
define_index do
indexes title
indexes body
indexes sub_categories(:title)
has created_at
has taggings(:tag_id), :as => :tag_ids, :facet => true
has companies_sub_categories :sub_category_id
has addresses :city_id
has :calculator_page # :without => {:calculator_page => 0}
has :site
has :reviews_count
end
sphinx, . :
rake ts:rebuild
:
Company.search ‘’
sphinx, . thinking-sphinx , . , .
ActiveRecord
guides.rubyonrails.org/association_basics.htmlguides.rubyonrails.org/active_record_querying.htmlclass Company < ActiveRecord::Base
acts_as_taggable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :trackable
belongs_to :image
has_many :weekly_newsletters, :class_name => 'Notice', :conditions => { :notice_type => 'weekly_newsletter' }
has_many :addresses
has_many :sub_categories, :through => :companies_sub_categories
validates :site,
:uniqueness => true,
:format => { :with => URI::regexp(%w(http https)) },
:allow_blank => true
validates :title, :presence => true, :uniqueness => true
validates :twitter_page, :format => { :with => URI::regexp(%w(http https)) },
:allow_blank => true
scope :by_rating, order('ratings_sum DESC')
scope :with_logo, where('image_id IS NOT NULL').includes(:image)
. . , orm .
State Machine
github.com/pluginaweek/state_machine/ .. .
# ActiveRecord model
state_machine :state, :initial => :moderate do
state :off, :human_name => ''
state :moderate, :human_name => ' '
state :published, :human_name => '' do
validates :uri, :presence => true
end
event :publish, :human_name => '' do
transition :off => :published
transition :moderate => :published
end
event :off, :human_name => '' do
transition :published => :off
end
end
(Rake, cron)
ru.wikipedia.org/wiki/Rakerake. , ,
pastebin.com/MavWT7JA. , . rake ruby. php —
pake.
#
namespace :app do
namespace :notice do
desc 'Weekly newsletter'
task :weekly_for_company => :environment do
Company.state.find_each do |company| # find_each batch
last_notice = company.weekly_newsletters.last
next if last_notice && (Time.now - last_notice.created_at < 1.week)
notice = company.weekly_newsletters.create
notice.save
CompanyMailer.weekly_newsletter(company).deliver
sleep(1)
end
end
end
end
:
rake app:notice:weekly_for_company
php, . .
Deploy (capistrano)
github.com/capistrano/capistrano/wikihabrahabr.ru/blogs/webdev/110021. (
):
cap deploy:migrations
, , , , , . .
(Bundler)
gembundler.combundler. . , , ( ) . . :
pastebin.com/50pe40Sb.
— Ancestry (use Materialized path)
— breadcrumbs_on_rails
— graticule
— acts-as-taggable-on
— paperclip
— foreigner
— rspec, factory_girl_rails, rcov
— capistrano, capistrano-ext, capistrano_colors
(Devise)
github.com/plataformatec/devise: Omniauthable, Confirmable, Recoverable, Registerable, Rememberable, Trackable, Timeoutable, Validatable, Lockable, Encryptable, Database Authenticatable, Token Authenticatable.
. . .
(Simple_Form)
github.com/plataformatec/simple_formZF, Django, . . Zend_Form ( zend_form ).
<%= simple_form_for(resource, :url => company_registration_path) do |f| %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= f.association :forma, :label_method => :title %>
<%= f.input :title %>
<%= f.association :sub_categories, :label_method => :title %>
<%= f.simple_fields_for :address do |address| %>
<%= address.association :city, :as => :select, :collection => cities(@company.address),
:input_html => { :id => "city_id" } %>
<%= address.input :street %>
<%= address.input :house, :required => false %>
<% end %>
<%= f.submit '' %>
<% end %>
.
(Rspec, FactoryGirl, Rcov)
habrahabr.ru/blogs/testing/52929github.com/thoughtbot/factory_girl:
pastebin.com/3tEctqmT:
pastebin.com/VmawXxbcFactoryGirl , , , . ( ). assert’.
php. , .
guides.rubyonrails.org/action_mailer_basics.htmlrusrails.ru/action-mailer-basicsrails . rails g mailer MailerName. . . : CompanyMailer.after_registration(@company).deliver
. Rails environment , ZF, : , , env. dev ( ) .
( ):
describe ColumnistMailer do
describe "after_registration" do
let(:mail) { ColumnistMailer.after_registration }
it "renders the headers" do
mail.subject.should eq("After registration")
mail.to.should eq(["to@example.org"])
mail.from.should eq(["from@example.com"])
end
it "renders the body" do
mail.body.encoded.should match("Hi")
end
end
end
github.com ( ) — .
newrelic.com — .
hoptoadapp.com/pages/home — . , php. ( ), — , , . , . , , . . , must have. js.
github.com/jdpace/errbit (Errbit is an open source, self-hosted error catcher. It is Hoptoad API compliant so you can just point the Hoptoad notifier at your Errbit server if you are already using Hoptoad).
php
github.com/rich/php-hoptoad-notifier. . , .
, , . , .