数据库查询,
设MemLevel是个数据库表:
=> MemLevel.where(code:'V1').name
=> #<ActiveRecord::Relation [#<MemLevel id: 2, code: "V1", name: "白银工长", score: 2000, created_at: "2017-06-08 01:02:03", updated_at: "2017-07-25 07:38:44", level: "1">]>
从代码可知获得的是键值为'V1'的、且为ActiveRecord::Relation类型的==数组==,[#<MemLevel...>]就是数组,数组里的#<MemLevel...>就是该数组的值(准确来说是哈希),这值说白了就是MemLevel表里的一行记录,从代码中知道该表里键值为'V1'的就一条记录。
所以在这里要想获得表里头:键code值为'V1'对应的键name值,得在获得上面的数组后,提取数组里的某一条记录(通常提取第一个就行),然后再从记录(哈希)挑出name的值,如下所示:
=> MemLevel.where(code:'V1').first
=> #<MemLevel id: 2, code: "V1", name: "白银工长", score: 2000, created_at: "2017-06-08 01:02:03", updated_at: "2017-07-25 07:38:44", level: "1">
=>MemLevel.where(code:'V1').first.name
=> "白银工长"
Ruby on Rails,ActiveRecord和ActiveRelation:
-
active record
注意是小写而且是两个单词。是一种编程模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。这使得我们能够方便地将数据库中的记录转化为实体对象,或将实体对象持久化到数据库中,以便业务代码中处理实体对象之间的关系而不再是数据库表记录之间的关系。
-
ActiveRecord
一个单词。是Rails对于这种模式的一种实现,以便我们更快速的实现对象在关系数据库中的持久化开发工作。业务中的实体类继承ActiveRecord,便能方便的将数据库中的记录与实体对象之间进行转换。更近一步,ActiveRecord是一种能够让你的实体对象变“聪明”的帮手,它能够根据自己的结构推知当前的数据库结构并能够和其交互以达到对象的增删改查。
比如说,对于某一个继承了ActiveRecord的User对象来说增删改查操作变得非常方便。我们一般来说都不用关心隐藏在后面的SQL语句编写工作,也就是说SQL语句对我们使用来说是完全透明的。
#insert
user=User.new
user.user_name="abbuggy"
user.save
#update
user.user_name="terry"
user.save
#delete
user.delete
-
ActiveRelation
这是Rails3版本中增加入的内容,是一个对象关系算法解析器。ActiveRelation能够将复杂的查询分解为简单的逐步调用,通过一系列基于上一次调用的结果上的调用完成复杂的查询,而不用去关心具体的SQL语句编写工作。大多数情况下ActionRelation是隐藏在幕后的,不被我们直接使用,我们能看到的只是对于ActionRecord的操作。
Rails布局和渲染
-
理解 yield
- 在rails布局中,yield标明一个区域,渲染的视图会插入这里。最简单的情况是只有一个 yield,此时渲染的整个视图都会插入这个区域.
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
- 布局中也可以标明多个区域,这个就需要使用具名yield,然后使用content_for方法。对于未命名的yield,视图的主体就会插入到未命名的yield区域。
#主布局 application.html.erb
<html>
<head>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html>
#子页面(e.g: app/views/admin/stores/index.html.erb)
<% content_for :head do %> #插入到主布局的 <%= yield :head %>位置
A simple page
<% end %>
<p>Hello, Rails!</p> #插入到主布局的 <%= yield %>位置
#最后生成的html
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, Rails!</p>
</body>
</html>
-
理解layouts
查找布局:
查找布局时,Rails 首先查看 app/views/layouts 文件夹中是否有和控制器同名的文件。例如,渲染 PhotosController 控制器中的动作会使用 app/views/layouts/photos.html.erb(或 app/views/layouts/photos.builder)。如果没找到针对控制器的布局,Rails 会使用 app/views/layouts/application.html.erb 或 app/views/layouts/application.builder。如果没有 .erb 布局,Rails 会使用 .builder 布局(如果文件存在)。Rails 还提供了多种方法用来指定单个控制器和动作使用的布局。
指定控制器所用布局:
在控制器中使用 layout 方法,可以改写默认使用的布局约定。例如:
class ProductsController < ApplicationController
layout "inventory"
#...
end
这么声明之后,ProductsController 渲染的所有视图都将使用 app/views/layouts/inventory.html.erb 文件作为布局。
要想指定整个程序使用的布局,可以在 ApplicationController 类中使用 layout 方法:
class ApplicationController < ActionController::Base
layout "main"
#...
end
这么声明之后,整个程序的视图都会使用 app/views/layouts/main.html.erb 文件作为布局。
运行时选择布局:
可以使用一个 Symbol,在处理请求时选择布局:
class ProductsController < ApplicationController
layout :products_layout
def show
@product = Product.find(params[:id])
end
private
def products_layout
@current_user.special? ? "special" : "products"
end
end
布局继承:
布局声明按层级顺序向下顺延,专用布局比通用布局优先级高。例如:
application_controller.rb
class ApplicationController < ActionController::Base
layout "main"
end
posts_controller.rb
class PostsController < ApplicationController
end
special_posts_controller.rb
class SpecialPostsController < PostsController
layout "special"
end
old_posts_controller.rb
class OldPostsController < SpecialPostsController
layout false
def show
@post = Post.find(params[:id])
end
def index
@old_posts = Post.older
render layout: "old"
end
# ...
end
在这个程序中:
- 一般情况下,视图使用 main 布局渲染;
- PostsController#index 使用 main 布局;
- SpecialPostsController#index 使用 special 布局;
- OldPostsController#show 不用布局;
- OldPostsController#index 使用 old 布局;