1、创建新项目simple_cms
rails new simple_cms -d mysql
2、在/config/database.yml中配置项目数据库信息
default: &default adapter: mysql2 encoding: utf8 pool: 5 username: anuo password: xxxxxx host: localhost development: <<: *default database: simple_cms_development
3、使用rake db:schema:dump
, 可以从现在的数据库创建schema文件。执行此命令后生成文件:/db/schema.rb
4、使用浏览器访问项目
- Start web server rails s
- 浏览器访问: http://localhost:3000/
5、生成控制器和视图
rails generate controller demo index: 生成名为demo的controller以及index的视图
routes.rb
6、服务器请求:浏览器发送请求,当在public里面存在与请求路径一致的文件时,直接返回该文件,如果不存在,则需要访问rails 服务。
7、路由
路由类型
Simple Match Route:
eg:get 'demo/index' match "demo/index", :to => "demo#index", :via => :get
Default Route Structure: :controller/:action/:id
eg: GET /student/edit/52 StudentController ,edit action ,id=52
Default Route:
eg: get ':controller(/:action(/:id))' match ':controller(/:action(/:id))', :via => :get
Root Route:
match "/" , :to => "demo#index", :via => :get
8、Render a template
Render template Syntax
render(:template => 'demo/hello')
render('demo/hello')
render('hello')
9、Redirect Actions
redirect_to( :action => 'hello')
redirect_to(:controller => 'test', :action => 'test') #跳转到testcontroller的test action
redirect_to("https://www.baidu.com")
会改变浏览器的访问地址
10、View templates
11、instance variables
def hello @array = ['Achris','Anuo','Janey','Monic','Alen'] render('hello') end
<% @array.each do |n|%>
<%= n %>,
<% end %>
12、Links
<a href="/demo/hello">Hello page 1</a><br> <%= link_to('Hello page 2',{:action => "hello"}) %><br> <%= link_to('Test test page',{:controller => 'test',:action => "test"}) %><br>
13、URL parameters
在index界面
<%= link_to('Hello page with parameters',{:action => "hello", :id => 20, :page => 5}) %><br>
在democontroller hello方法里面对参数处理:
def hello @array = ['Achris','Anuo','Janey','Monic','Alen'] @id =params['id'] @page = params[:page] render('hello') end
在hello.html.erb里面参数使用
ID: <%= @id%><br> ID:<%= params['id'] %><br> Page:<%= params[:page] %><br> <!--参数默认是string,进行数学计算时需要转化no implicit conversion of Fixnum into String--> nextPage: <%= params[:page].to_i + 1 %><br>
14、Generate migrations
rails generate migration DoNothingYet
15、Generate models
rails generate model User
20170320090551_create_users.rb内容(修改)
class CreateUsers < ActiveRecord::Migration[5.0] def up create_table :users do |t| t.column "first_name", :string, :limit =>25 t.string "last_name", :limit => 50 t.string "email", :default => '', :null => false t.string "password", :limit =>40 t.timestamps #t.datetime "created_at" #t.datetime "uploaded_at" end end def down drop_table :users end end
16、Run migrations
rails db:migrate
回滚(撤回):rails db:migrate VERSION=0
查看数据库版本:rails db:migrate:status
rails db:migrate VERSION=20170320090551
17、Migration methods
例子
rails generate migration AlterUsers
20170320090551_create_users.rb内容:
class AlterUsers < ActiveRecord::Migration[5.0] def up rename_table("users","admin_users") add_column("admin_users","username", :string, :limit =>25, :after => "email") change_column("admin_users","email", :string, :limit =>100) rename_column("admin_users","password","hashed_password") puts "****Adding an index****" add_index("admin_users","username") end def down remove_index("admin_users","username") rename_column("hashed_password","password") change_column("email", :string, :default => '', :null => false) remove_column('admin_users',"username") rename_table("admin_users","users") end end
rails db:migrate
18、Solve migration problems
当执行错误的时候,解决办法:修改migrate file ,注释出错文件中已执行的语句,再次执行rails db:migrate ,当down时,类似
19、Challenge Migrations for the CMS
rails generate model Subject
rails generate model Page
rails generate model Section
20170321014824_create_subjects.rb
20170321014839_create_pages.rb
20170321014855_create_sections.rb
rails db:migrate
20、撤回到之前版本
rails db:migrate:status
rails db:migrate VERSION=20170320100921
21、ActiveRecord and ActiveRelation
Active Record 是 MVC 中的 M(模型),负责处理数据和业务逻辑。Active Record 负责创建和使用需要持久存入数据库中的数据。Active Record 实现了 Active Record 模式,是一种对象关系映射系统。
Active Record 模式出自 Martin Fowler 写的《企业应用架构模式》一书。在 Active Record 模式中,对象中既有持久存储的数据,也有针对数据的操作。Active Record 模式把数据存取逻辑作为对象的一部分,处理对象的用户知道如何把数据写入数据库,还知道如何从数据库中读出数据。
对象关系映射(ORM)是一种技术手段,把应用中的对象和关系型数据库中的数据表连接起来。使用 ORM,应用中对象的属性和对象之间的关系可以通过一种简单的方法从数据库中获取,无需直接编写 SQL 语句,也不过度依赖特定的数据库种类。
用作 ORM 框架的 Active Record提供了很多功能,其中最重要的几个如下:
1、表示模型和其中的数据;
2、表示模型之间的关系;
3、通过相关联的模型表示继承层次结构;
4、持久存入数据库之前,验证模型;
5、以面向对象的方式处理数据库操作。
22、Model naming
已经讲users表改名为admin_users,有两种方法让model与table挂钩:1、在user.rb文件中self.table_name="admin_users";2、将user.rb更改为admin_user.rb,更改class名User为AdminUser。
23、Model attributes
24、Create records
方法1:
1)subject1=Subject.new
2)subject1.name="First Subject"
3)subject.save
方法1的前两个步骤可以异步到位: subject =Subject.new(:name => "First Subject",:position => 1, :visible => true)
方法2:
1)subject=Subject.create(:name => "Second Subject",:position => 2, :visible => true)
25、Update records
方法1: find/setValue/save
1) subject =Subject.find(1)
2)subject.name="Initial Subject"
3) subject.save
方法2:Find/setValue and save
1)subject =Subject.find(2)
2)subject1.update_attributes(:name => 'Next Subject', :visible => false)
26、Delete records
方法:Find/Destroy
准备工作先创建一个subject : Subject.create(:name => "Bad Subject")
1)subject=Subject.find(3)
2) subject.destroy
subject.destroy之后,记录不存在在数据库,但是对象subject仍然存在在应用中,但是不能更改对象subject的任意值。
27、Find records
Primary key finder :Subject.find(id) ,当根据id找不到数据时报错ActiveRecord::RecordNotFound: Couldn't find Subject with 'id'=3
Dynamic finders: Subject.find_by_attrName subject=Subject.find_by_id(3),当找不到数据时,返回nil
Find all: subjects=Subject.all
Find last/first
28、Query methods Conditions
where(conditions)
29、Query methods Order, limit, and offset
30、Named scopes
class Subject < ApplicationRecord scope :visible, lambda { where(:visible => true)} scope :invisible, lambda { where(:visible => false)} scope :sorted, lambda {order(:position => :asc)} scope :newest_first, lambda{order(:created_at => :desc)} scope :search, lambda{|query| where(["name like ?","%#{query}%"]) } end
31、Relationship types
32、One to one associations
我们假定subject has_one page,page belongs_to subject,
1、class with "belongs_to" has the foreign key;
2、always define both sides of the relationship
/app/models/subject.rb
/app/models/page.rb
destroy association
上面命令执行后关系取消,但是page的数据依然存在在数据中
33、One to many associations
subject has_many pages,page belongs_to subject,
/app/models/subject.rb
/app/models/page.rb
34、belongs to presence validation
更改page之后
35、Many to many associations Simple
实例:
step1:
step2:/db/migrate/20170323055150_create_admin_users_pages_join.rb
step 3:
step 4:修改admin_user以及page
测试:
step 1:创建一个新的用户
step 2:找到一个page
step 3:建立关系
36、Many to many associations Rich
实战:
/db/migrate/20170323075236_create_section_edits.rb
/app/models/admin_user.rb
/app/models/section.rb
/app/models/section_edit.rb
测试:
找到可用的admin_user以及section
生成edit
单独保存
可行的做法:
37、Traverse a rich association
此节的目的在于将admin_user和section建立直接连接,即可通过admin_user.sections/section.admin_users获得。。。这建立在上节的基础上
/app/models/admin_user.rb
/app/models/section.rb
测试:
38、CRUD
rails generate controller Subjects index show new edit delete
39、REST
40、Resourceful routes
41、Resourceful URL helpers
42、Read action Index
/app/controllers/subjects_controller.rb
def index @subjects = Subject.sorted end
/app/views/subjects/index.html.erb
<div class="subject index"> <h2>Subjects</h2> <%= link_to("Add New Subject", "#", :class => "action new") %> <table class="listing" summary="Subject list"> <tr class="header"> <th>#</th> <th>Subject</th> <th>Visible</th> <th>Pages</th> <th>Actions</th> </tr> <% @subjects.each do |subject| %> <tr> <td><%= subject.position %></td> <td><%= subject.name %></td> <td class="center"><%= subject.visible ? 'YES' : 'NO' %></td> <td class="center"><%= subject.pages.size%></td> <td class="actions"> <%= link_to("Show", "#", :class => "action show") %> <%= link_to("Edit", "#", :class => "action edit") %> <%= link_to("Delete", "#", :class => "action delete") %> </td> </tr> <% end %> </table> </div>
43、Read action Show
修改index.rb文件
修改/app/controllers/subjects_controller.rb
<%= link_to("Back to list", subjects_path, :class => "back_link") %> <div class="subject show"> <h2>Show Subject</h2> <table summary="Subject detail view"> <tr> <th>Name</th> <td><%= @subject.name %></td> </tr> <tr> <th>Position</th> <td><%= @subject.position %></td> </tr> <tr> <th>Visible?</th> <td class="center"><%= @subject.visible ? 'YES' : 'NO' %></td> </tr> <tr> <th>Created</th> <td><%= @subject.created_at %></td> </tr> <tr> <th>Updated</th> <td><%= @subject.updated_at %></td> </tr> </table> </div>
44、Form basics
45、Create action New
index.rb
修改/app/controllers/subjects_controller.rb
/app/views/subjects/new.html.erb
<%= link_to("Back to list", subjects_path, :class => "back_link") %> <div class="subject new"> <h2>Create Subject</h2> <%= form_for(@subject) do |f| %> <table summary="Subject form fields"> <tr> <th>Name</th> <td><%= f.text_field(:name) %></td> </tr> <tr> <th>Position</th> <td><%= f.text_field(:position) %></td> </tr> <tr> <th>Visible</th> <td><%= f.text_field(:visible) %></td> </tr> </table> <div class="form-buttons"> <%= f.submit("Create Subject") %> </div> <% end %> </div>
46、Create action Create
def create # Instantiate a new object using form parameters @subject =Subject.new(params[:subject]) # Save the Object if @subject.save #If save succeeds,redurect to the index action redirect_to(subjects_path) else # If save fails, redisplay the form so the user can fix problems render("new") end end
47、Strong parameters
48、Update actions Edit update
49、Delete actions Delete destroy
/app/views/subjects/index.html.erb
/app/controllers/subjects_controller.rb
/app/views/subjects/delete.html.erb
50、Flash hash
在redirect之前个步骤操作结果提示
/app/controllers/subjects_controller.rb
/app/views/subjects/index.html.erb 头部添加
51、Layout
在/app/views/layouts文件夹内新建文件admin.html.erb
<!DOCTYPE html> <html> <head> <title>Simple CMS: <%= @page_title || "Admin Area" %></title> </head> <body> <% if !flash[:notice].blank? %> <div class="notice"> <%= flash[:notice] %> </div> <% end %> <!-- before yield --> <%= yield %> <!-- after yield --> </body> </html>
在controller引用layout
去掉html.erb文件里面之前的notice部分的代码,已经在layout里面体现,并增加页面信息
52、Partial templates
创建/app/views/subjects/_form.html.erb,将edit以及create表单部分内容复制到_form.html.erb里面
new喝edit页面去掉表单已加到_form.html.erb的内容,用<%= render(:partial =>'form', :locals => { :f => f}) %>指代内容
53、Text helpers
TextHelper模块提供了一组过滤,格式化和转换字符串的方法,可以减少视图中的内置Ruby代码的数量。 这些帮助方法扩展了Action View,使它们可以在模板文件中调用。
54、
55、
56、
57、
58、
59、
60、