рд▓рдЧрднрдЧ рдкрд╛рдВрдЪ рдорд╣реАрдиреЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рдЬрд╝реЗрдВрдб рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рд╕рдордЭреМрддрд╛ рдХрд┐рдпрд╛ рдФрд░ рд░реЗрд▓ рдкрд░ рдЪрд▓рд╛ рдЧрдпрд╛ред рдлрд┐рд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ
www.okinfo.ru рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдЕрдм рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдврд▓рд╛рди рдиреЗ рджрд┐рдЦрд╛рдпрд╛ рд╣реИ рдХрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 15000 рд╕реЗ рдШрдЯрдХрд░ 4000 рд╣реЛ рдЧрдИ рд╣реИред рдореЗрд░реЗ рджреЛрд╕реНрддреЛрдВ php рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдПрдХ рд╕рдлрд▓ рдХрд╣рд╛рдиреА рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЬрдиреНрдо рд╣реБрдЖред рдЗрд╕рдореЗрдВ, рдореИрдВ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдХреИрд╕рд╛ рдерд╛, рд╕рд╛рде рд╣реА рдорд╛рдгрд┐рдХ рдореЗрдВ рдореЗрд░реЗ рд╕рдВрдХреНрд░рдордг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рд╕реА рдмрд╛рддред
рдкреНрд░рд╛рдЧрд┐рддрд┐рд╣рд╛рд╕
рд▓рдЧрднрдЧ рджреЛ рд╡рд░реНрд╖реЛрдВ рдХреЗ
рд▓рд┐рдП www.starlook.ru рдХреЗ рдореБрдЦреНрдп рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдЙрд╕ рдмрд┐рдВрджреБ рдкрд░ рдкрд╣реБрдВрдЪ рдЧрдпрд╛, рдЬрд╣рд╛рдВ рдЖрдк рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдХреЛ рдиреАрдЪреЗ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдХреЛрдб рдЖрдорддреМрд░ рдкрд░ рдареАрдХ-рдареАрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╕рдВрдкреВрд░реНрдг рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реНрдкрд╖реНрдЯ рдФрд░ рдбреАрдмрдЧ рдХреА рдЧрдИ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдЦреА рдЧрдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдФрд░ рд╕рдорд░реНрдерди рдХреЛ рдЬрд╛рд░реА рд░рдЦрд╛ред рдЗрд╕ рд╕рдордп, рдордЬрд╝реЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ django рдФрд░ рд░реЗрд▓ рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рд░рдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдореБрдЭреЗ рдПрдХ рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдЬрдЧрд░ рдкрд╕рдВрдж рдерд╛, рд▓реЗрдХрд┐рди django рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдерд╛ред рдФрд░ рд░реЗрд▓ рдФрд░ рд░реВрдмреА рдХреЗ рд╕рд╛рде рд╕реНрдерд┐рддрд┐ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдереАред рдЗрд╕реЗ рдкрд╣рд▓реА рдирдЬрд░ рдореЗрдВ рдкреНрдпрд╛рд░ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рд╢рд╛рдмреНрджрд┐рдХ рдЕрдзреНрдпрдпрди рдХреЗ рдПрдХ рдорд╣реАрдиреЗ рдХреЗ рдмрд╛рдж, рдорд╛рдИ рд╕рд░реНрдХрд▓ рдореЗрдВ рдПрдХ рдкрддреНрд░ рдорд╛рдгрд┐рдХ рдбреЗрд╡рд▓рдкрд░ рдХреА рд░рд┐рдХреНрддрд┐ рдкрд░ рдПрдХ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рдЖрдпрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдПрдХ рджреБрд░реНрдШрдЯрдирд╛ рдереА, рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдкреНрд░реЗрд╖рдХ рдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдореИрдВ рдорд╛рдгрд┐рдХ рдЬрд╛рдирддрд╛ рд╣реВрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рднрд╛рдЧреНрдп рдерд╛, рдФрд░ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╡реЗ рдЕрднреА рднреА рдореБрдЭреЗ рдПрдХ рдирдИ рдЬрдЧрд╣ рдкрд░ рдПрдХ
рд╣реИрдХ рдореЗрдВ рд▓реЗ рдЧрдПред
рдХреНрдпреЛрдВ?
рд░реЗрд▓реЛрдВ рдХреЛ рдЬрд╛рдирдиреЗ рдХреЗ рдмрд╛рдж, ZF рдкрд░ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд▓рд┐рдЦрдирд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рдерд╛, рдореБрдЭреЗ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рд╕реЗ рдмрд╣реБрдд рдХреБрдЫ рдХрд░рдирд╛ рдерд╛ рдФрд░ рд▓рдЧрднрдЧ рд╣рд░ рдХрд╛рд░реНрдп (рдЯреИрдЧ, рдкреЗрдбрд╝, рддреИрдирд╛рддреА, рдорд╛рдЗрдЧреНрд░реЗрд╢рди, рдЖрджрд┐) рдкрд░ рдЕрдкрдиреЗ рдЦреБрдж рдХреЗ рдлреИрд╕рд▓реЗ рд▓рд┐рдЦрдиреЗ рдереЗред рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдЗрддрдирд╛ рдЦрд╛рд▓реА рд╕рдордп рдирд╣реАрдВ рд╣реИ, рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛, рдПрдХ рдкрддреНрдерд░ рд╕реЗ рджреЛ рдкрдХреНрд╖рд┐рдпреЛрдВ рдХреЛ рдорд╛рд░ рджрд┐рдпрд╛ рдЧрдпрд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЙрдирдХреЗ рд╡рд┐рдХрд╛рд╕ рдФрд░ рд╕рдорд░реНрдерди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рджреВрд╕рд░реА рдмрд╛рдд, рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпреЛрдВ рдкрд░ рдЬреНрдЮрд╛рди рдХреЛ рдХрд╕рдиреЗ рдХреЗ рд▓рд┐рдПред
рдкрд░реНрдпрд╛рд╡рд░рдг рдХреА рд╕реНрдерд╛рдкрдирд╛
rvm.beginrescueend.com - рд░реВрдмреА рдХреЗ рдХрдИ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреА рд╕реНрдерд╛рдкрдирд╛ рдФрд░ рд░рддреНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдердиред
en.wikipedia.org/wiki/RubyGems - рд░рддреНрди
sudo 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. . , .
, , . , .