remote: true
(data-remote="true"
)
rails
gem install rails
Action Pack
— съставен от Action Controller
, Action Dispatch
и Action View
Action Mailer
— изпращане на мейли по културен начин
Active Model
— валидации, преводи, callback-функции и много други
Active Record
— ORM към релационни бази от типа на PostgreSQL, MySQL, SQLite и т.н.
Active Resource
— CRUD на отдалечени ресурси
Active Support
— разширения на стандартната Ruby библиотека с различни благинки
Railties
— код-лепило между отделните компоненти, документация, guides и прочее<div id="profile">
<div class="left column">
<div id="date"><%= print_date %></div>
<div id="address"><%= current_user.address %></div>
</div>
<div class="right column">
<div id="email"><%= current_user.email %></div>
<div id="bio"><%= current_user.bio %></div>
</div>
</div>
#profile .left.column #date= print_date #address= current_user.address .right.column #email= current_user.email #bio= current_user.bio
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
scope :admins, where(admin: true)
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
Няма да ги има в Rails 4!
david = User.find_by_name_and_age('David', 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, '2012-12-10 19:58:13', '2012-...')
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
, ...module Institute
class Workshop < ActiveRecord::Base
has_many :events
end
class Event < ActiveRecord::Base
def self.past
# Използваме ARel да конструираме по-сложни условия
where arel_table[:end_date].lt(Date.current)
end
end
end
Institute::Workshop.joins(:events).merge(Institute::Event.past)
# SELECT `institute_workshops`.* FROM `institute_workshops`
# INNER JOIN `institute_events` ON
# `institute_events`.`workshop_id` = `institute_workshops`.`id`
# WHERE (`institute_events`.`end_date` < '2012-12-10')
class Product < ActiveRecord::Base
validates_presence_of :price, :description
validates_numericality_of :price, 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
def show
@project = Project.find(params[:id])
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
bundle exec 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
bundle exec rails generate
bundle exec rake -T
ще ви покаже списък, заедно с описания
bundle exec rake some:task:name['Arguments']
config/locales/