rails
gem install rails
rails new myapp
)Action Pack
— съставен от Action Controller
, Action Dispatch
и Action View
Active Model
— валидации, преводи, callback-функции и много други, свързани с модели; не се занимава с persistence
Active Record
— ORM към релационни бази от типа на PostgreSQL, MySQL, SQLite и т.н.; надгражда над Active Model
Action Mailer
— изпращане на мейли по културен начин; наподобява Action Controller
Active Support
— разширения на стандартната Ruby библиотека с различни благинки
Railties
— код-лепило между отделните компоненти, документация, guides и прочееrails new quizzes
: 38 directories, 40 files
quizzes ├── app │ ├── assets │ ├── controllers │ ├── helpers │ ├── mailers │ ├── models │ └── views ├── bin ├── config │ ├── environments │ ├── initializers │ └── locales ├── db ├── lib │ └── tasks ├── log ├── public ├── test │ ├── controllers │ ├── fixtures │ ├── integration │ ├── mailers │ └── models ├── tmp └── vendor
<div id="profile">
<% if user_signed_in? %>
Здравейте, <%= current_user.email %>.
<%= link_to 'Изход', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'Вход', new_user_session_path %> |
<%= link_to 'Регистрация', new_user_registration_path %>
<% end %>
</div>
#profile
%p
- if user_signed_in?
Здравейте, #{h current_user.email}.
= link_to 'Изход', destroy_user_session_path, method: :delete
- else
= link_to 'Вход', new_user_session_path
|
= link_to 'Регистрация', new_user_registration_path
#profile
p
- if user_signed_in?
' Здравейте, #{current_user.email}.
== link_to 'Изход', destroy_user_session_path, method: :delete
- else
== link_to 'Вход', new_user_session_path
' |
== link_to 'Регистрация', new_user_registration_path
doctype html
html
head
title Slim Core Example
meta name="keywords" content="template language"
body
h1 Markup examples
div id="content" class="example1"
p Nest by indentation
ActiveRecord
Mongoid
за MongoDB
)
class User < ActiveRecord::Base
# Много неща идват наготово по конвенция
# Таблицата в случая е users (по конвенция)
end
class User < ActiveRecord::Base
def self.admins
where(admin: true)
end
end
admin = User.admins.where(email: 'root@foo.bar').first
# Ще генерира следната заявка към MySQL база:
#
# SELECT `users`.* FROM `users` WHERE `users`.`admin` = 1
# AND `users`.`email` = 'root@foo.bar' LIMIT 1
admin.email # 'root@foo.bar'
admin.name # 'Charlie Sheen'
admin.name = "Charlie's Angels"
admin.save
# UPDATE `users` SET
# `users`.`name` = 'Charlie\'s Angels',
# `users`.`updated_at` = '2012-12-10 19:48:03'
# WHERE `users`.`id` = 42
david = User.find_by_name_and_age('David', 33)
# или:
david = User.find_by(name: 'David', age: 33)
# SELECT `users`.* FROM `users` WHERE
# `users`.`name` = 'David' AND `users`.`age` = 33
# LIMIT 1
lastest_signups = User.where(confirmed: true)
.order(:created_at).last(5)
# SELECT `users`.* FROM `users` WHERE `users`.`confirmed` = 1
# ORDER BY created_at DESC LIMIT 5
class Book < ActiveRecord::Base
end
class Publisher < ActiveRecord::Base
has_many :books
end
vintage = Publisher.find(42)
vintage.books
# SELECT `publishers`.* FROM `publishers` WHERE `publishers`.`id` = 42 LIMIT 1
# SELECT `books`.* FROM `books` WHERE `books`.`publisher_id` = 42
class Book < ActiveRecord::Base
end
class Publisher < ActiveRecord::Base
has_many :books
end
vintage = Publisher.find(42)
vintage.books.create name: 'Rails Recipes'
# INSERT INTO `books` (`name`, `publisher_id`, `created_at`, `updated_at`)
# VALUES ('Rails Recipes', 42, '2016-01-04 19:58:13', '2016-...')
class Author < ActiveRecord::Base; end
class Book < ActiveRecord::Base
belongs_to :author
end
class Publisher < ActiveRecord::Base
has_many :books
has_many :authors, through: :books
end
Publisher.find(42).authors
# SELECT `authors`.* FROM `authors` INNER JOIN
# `books` ON `books`.`author_id` = `authors`.`id`
# WHERE `books`.`publisher_id` = 42
arel
), за да конструира SQL
where
, order
, joins
, include
, limit
, take(x)
, last(x)
, count
, size
, ...class Venue < ActiveRecord::Base
has_many :events
end
class Event < ActiveRecord::Base
def self.past
# Use ARel to construct a more complex query
where arel_table[:end_date].lt(Date.current)
end
end
Venue.joins(:events).merge(Event.past)
# SELECT `venues`.* FROM `venues`
# INNER JOIN `events` ON `events`.`venue_id` = `venues`.`id`
# WHERE (`events`.`end_date` < '2016-01-04')
class Product < ActiveRecord::Base
validates :description, presence: true
validates :price, presence: true, numericality: {greater_than_or_equal_to: 0}
end
# Не запазва нищо в базата следствие на
# неуспешна валидация.
product = Product.create
product.errors.full_messages
# ["Price can't be blank", "Description can't be blank",
# "Price is not a number", "Price must be greater than or equal to 0"]
Mongoid
ActiveRecord
ActiveModel
request
)
params
, session
, cookies
, response
, ...
class ProjectsController < ApplicationController
# Called when the user requests /projects/123 via HTTP GET
def show
@project = Project.find(params[:id]) # params[:id] == "123"
end
end
params
е хеш с параметрите от query string + URI + POST body
app/views/projects/show.html.erb
@project
е достъпно в изгледаclass ProjectsController < ApplicationController
def show
@project = Project.find(params[:id])
end
def edit
@project = Project.find(params[:id])
end
end
class ProjectsController < ApplicationController
before_filter :load_project
def show() end
def edit() end
private
def load_project
@project = Project.find(params[:id])
end
end
show
"визуализира" ресурса, достъпно само през HTTP GET
new
форма за създаване на ресурс, POST-ва към create
edit
форма за редактиране на ресурса, ще POST-не към update
create
за създаване на ресурс, достъпно през HTTP POST
update
за обновяване на ресурс, достъпно през HTTP PUT
destroy
за унищожаване на ресурс, достъпно през HTTP DELETE
class ProjectsController < ApplicationController
before_filter :load_project
def update
if @project.update_attributes(params[:project])
# Препраща към ProjectsController#show()
redirect_to @project, notice: 'Промените са съхранени успешно.'
else
render action: :edit
end
end
end
HTTP 302
към show
edit
)
new
/create
config/routes.rb
със собствен DSL
bin/rake routes
ще ви покаже списък с текущите маршрутиTodo::Application.routes.draw do
resources :projects
end
Rails.application.routes.draw do
resources :activations, constraints: {id: /.+/}
resources :vouchers, only: [:index, :new, :create]
resources :announcements, except: [:show, :destroy]
resources :quizzes
resource :profile
resource :dashboard, only: :show
resources :tasks, except: :destroy do
get :guide, on: :collection
resources :solutions
resource :check, controller: :task_checks, only: :create
end
mount Sidekiq::Web => '/queue'
root to: 'home#index'
end
match
match
match
и ще овладеете маршрутите в Railsmount
може да закачате готови Rack-приложения на даден URL
mount
пак вика match
вътрешноГенериране на URL-и посредством "route helpers"
new_project_path() # "/projects/new"
project_path(project) # "/projects/123"
new_project_document_path(project) # "/projects/123/documents/new"
# Source
<header>
<%= image_tag 'logo.png', class: 'logo' %>
</header>
# В development
<header>
<img src="/assets/logo.png" alt="Logo" class="logo" />
</header>
# В production
<header>
<img src="/assets/logo-9692fa42c3.png" alt="Logo" class="logo" />
</header>
up()
и down()
методи
down()
на миграциите
class CreateTodos < ActiveRecord::Migration
def up
create_table :todos do |t|
t.text :text, null: false
t.boolean :done, null: false, default: false
t.integer :user_id, null: false
t.timestamps # created_at, updated_at
end
add_index :todos, :user_id
end
def down
remove_index :todos, :user_id
drop_table :todos
end
end
class CreateTodos < ActiveRecord::Migration
def change
create_table :todos do |t|
t.text :text, null: false
t.boolean :done, null: false, default: false
t.integer :user_id, null: false
t.timestamps # created_at, updated_at
end
add_index :todos, :user_id
end
end
Gemfile
Gemfile
, и Gemfile.lock
във version control
bin/rails generate
bin/rake -T
ще ви покаже списък, заедно с описания
bin/rake some:task:name['Arguments']
config/locales/
globalize
)