Zend рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рд░реЗрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдирд╛

рд▓рдЧрднрдЧ рдкрд╛рдВрдЪ рдорд╣реАрдиреЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рдЬрд╝реЗрдВрдб рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рд╕рдордЭреМрддрд╛ рдХрд┐рдпрд╛ рдФрд░ рд░реЗрд▓ рдкрд░ рдЪрд▓рд╛ рдЧрдпрд╛ред рдлрд┐рд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ 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 . . .



image



netbeans vim.



REST



habrahabr.ru/blogs/webdev/38730

guides.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.html

guides.rubyonrails.org/active_record_querying.html



class 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/Rake





rake. , , 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/wiki

habrahabr.ru/blogs/webdev/110021



. ( ):



cap deploy:migrations

      
      







, , , , , . .



(Bundler)



gembundler.com



bundler. . , , ( ) . . : 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_form



ZF, 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/52929

github.com/thoughtbot/factory_girl



: pastebin.com/3tEctqmT

: pastebin.com/VmawXxbc



FactoryGirl , , , . ( ). assertтАЩ.



php. , .





guides.rubyonrails.org/action_mailer_basics.html

rusrails.ru/action-mailer-basics



rails . 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





. . , .



, , . , .



All Articles