Ruby学习笔记4: 动态web app的建立

We will first build the Categories page. This page contains topics like Art, Home & Living, and Kids, so our users can browse through categories and find what they like.

Each Category in our site will need to store information about itself, such as a name and an image. Our Category Model is what stores information about our Categories. Remember that our Model manages the data in our app.

===============================

1. Build Model

2. Build Migration Table

3. Add Data to Tables

4. Generate Table Controller

5.

===============================

1. Build our Model

开始之前,我们要先建立Model用来存储每个Category的数据模型。

We can generate a Model with the following rails command:

rails generate model Person

Here Person is an example name for our Model. Model names are always singular.

这里,我们建立一个叫做Category的Model:

In your terminal, generate a model named Category using the rails command. Press Enter.

rails generate model Category

In terminal:

$ rails generate model Category
invoke active_record
create db/migrate/20141013165110_create_categories.rb
create app/models/category.rb
invoke test_unit
create test/models/category_test.rb
create test/fixtures/categories.yml
$

2. Build our Migration table

Our Model is fine for now. Let's prepare our Migration table. We do this in two steps:

a. We add columns to our Category Migration table. These will define what information our database can accept.

b. We type bundle exec bundle exec rake db:migrate in our terminal to migrate our database, or update its state.

Let's look at an example. Say we had a Person Model, and we want it to have the columns name and age. In the Migration table, we add columns like this:

def change

  create_table :person do |t|

    t.string :name

    t.integer :age

    t.timestamps

  end

end

Above we add t.string :name andt.integer
:age
 specifying the name of type string and the age of type integer. We run db:migrate to add a name and age column to our
actual database.

Instructions
1.

Add a name and thumburl attributes to your category migrations. These are both strings. Hit Run.

2.

In your terminal, runbundle exec rake db:migrate to migrate your database. Press Enter.

class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.string :name
t.string :thumburl
#t.timestamps
end
end
end

Terminal:

$ bundle exec rake db:migrate
== 20140626211003 CreateCategories: migrating =================================
-- create_table(:categories)
-> 0.0010s
== 20140626211003 CreateCategories: migrated (0.0010s) ======================== $

3. Add data to Tables

Now that we have columns, we need to add data. This file(in the
seeds.rb file) on the below might look intimidating, but it is a simple list of data for our Rails app.

# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first) art = Category.create(name: 'Art', thumburl: 'http://upload.wikimedia.org/wikipedia/commons/e/eb/144-la_fuente_de_Monforte_V.jpg')
home_and_living = Category.create(name: 'Home & Living', thumburl: 'http://ihomedecorsideas.com/wp-content/uploads/2014/04/diy_network_homemade_coat_rack_.jpg')
jewelry = Category.create(name: 'Jewelry', thumburl: 'http://upload.wikimedia.org/wikipedia/commons/f/ff/Midyat_Silver_Jewelry_1310103_Nevit.jpg')
women = Category.create(name: 'Women', thumburl: 'https://c1.staticflickr.com/9/8255/8660920433_57a184d9d1_z.jpg')
men = Category.create(name: 'Men', thumburl: 'http://upload.wikimedia.org/wikipedia/commons/d/d5/Fullbrogue_(Grenson).jpg')
kids = Category.create(name: 'Kids', thumburl: 'http://upload.wikimedia.org/wikipedia/commons/e/e0/Artist%27s_Paint_Brushes_Adapted_With_Photoshop._Surrey_UK.jpg')
vintage = Category.create(name: 'Vintage', thumburl: 'https://c2.staticflickr.com/8/7402/9426557291_139134efaa_z.jpg')
weddings = Category.create(name: 'Weddings', thumburl: 'http://hostingessence.com/wp-content/uploads/2012/04/green-wedding.jpg')
# Add your category here

How does this work? We store data in two steps.

a. We first add seed data in the seeds.rb file

b. We run rake db:seed in our terminal.

已经加了数据在例子里,这里再练习一下seeding data : Let's look at a small example first.

gia = Person.create(name: 'Gia', age: '8')

Here we create a new object in the Person class with the name Gia and age8. We store this object in a variablegia.

Now let's look at some seed data for Category.

weddings = Category.create(name: 'Weddings', thumburl: 'http://hostingessence.com/wp-content/uploads/2012/04/green-wedding.jpg')

Here, we create a new object in the Category class with the name of Weddings and athumburl. We store this in the variable weddings.

=========== Instructions ===========

<1>.

Look in your seeds file, seeds.rb. On line 17, add seed data for craft_supplies. The entry should have a name'Craft Supplies' and a thumburl of'http://bit.ly/1w1uPow'. Store this entry in a variable called craft_supplies.
Hit Run.

<2>.

In your terminal, run rake db:seed [更正:bundle exec rake db:seed ] to add the data from
seeds into your database. Press Enter.

in seeds.db file, add below at line 17:

  # Add your category here:
craft_supplies = Category.create(name:'Craft Supplies',thumburl:'http://bit.ly/1w1uPow')

in Terminal, type this command and hit Enter:

$ rake db:seed
rake aborted!
Gem::LoadError: You have already activated rake 10.4.2, but your Gemfile requires rake 10.3.2. Prepending `bundle exec` to your command may solve this.
/var/lib/gems/2.0.0/gems/bundler-1.7.3/lib/bundler/runtime.rb:34:in `block in setup'
/var/lib/gems/2.0.0/gems/bundler-1.7.3/lib/bundler/runtime.rb:19:in `setup'
/var/lib/gems/2.0.0/gems/bundler-1.7.3/lib/bundler.rb:121:in `setup'
/var/lib/gems/2.0.0/gems/bundler-1.7.3/lib/bundler/setup.rb:17:in `<top (required)>'
/home/ccuser/workspace/ecommerce-rails-app/config/boot.rb:4:in `<top (required)>'
/home/ccuser/workspace/ecommerce-rails-app/config/application.rb:1:in `<top (required)>'
/home/ccuser/workspace/ecommerce-rails-app/Rakefile:4:in `<top (required)>'
(See full trace by running task with --trace)
$

我们得到一个错误:rake aborted! 看它的说明,使用这个命令即可:

$ bundle exec rake db:seed

OK.

4.Generate table Controller

建立了数据库操作的基本东东,但目前我们table里的数据是static的,所以我们又要建立Controller,让我们来改变页面里的内容。

但目前我们table里的数据是static的,所以我们又要建立Controller,让我们来改变页面里的内容。In Rails,数据库操作的五个主要的方式methods: index, show, new, edit, delete. 这几个在动态Rails App里是一样的,对以后的学习有帮助。

还记得我们建立Persons Controller时候用的命令吗?

>>  rails genertate controller Persons

所以我们就可以在命令行里添加methods,同时,Rails会updates相关的routes和Views for us.

例如,如果我们想要添加 index ,new, edit 这三个mothods到Persons这个Controller,使用如下的命令:

>>  rails generate controller Persons index new edit

注:一般Controller的名字是plural复数,Model的名字是单数。

【好,这里的操作】1.In your terminal, generate a controller Categories with the main methods we’ll use: index, show, new, edit, and delete. Press Enter.

>>  rails generate controller Categories index show new edit delete

$ rails generate controller Categories index show new edit delete
create app/controllers/categories_controller.rb
route get 'categories/delete'
route get 'categories/edit'
route get 'categories/new'
route get 'categories/show'
route get 'categories/index'
invoke erb
create app/views/categories
create app/views/categories/index.html.erb
create app/views/categories/show.html.erb
create app/views/categories/new.html.erb
create app/views/categories/edit.html.erb
create app/views/categories/delete.html.erb
invoke test_unit
create test/controllers/categories_controller_test.rb
invoke helper
create app/helpers/categories_helper.rb
invoke test_unit
create test/helpers/categories_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/categories.js.coffee
invoke scss
create app/assets/stylesheets/categories.css.scss
$

done!这样我们就又建立了一个Controller,里面有操作数据库的5个methods,如下:

catogories_controller.rb文件:

class CategoriesController < ApplicationController
def index
end def show
end def new
end def edit
end def delete
end
end

然后我们就要来写这些methods里的具体的语句。

---<1>---关于安全

但是,开始之前,我们要保证从model来的数据的安全,所以:

There's one step we do before writing our main Controller methods: we need our Controller to have a secure way of getting information from our Model.

We'll use a private method to do this called
strong parameters. This method prevents a user from hacking into our app and changing our Model.

要让method ”strong parameters“ 变得private从而阻止黑客入侵。首先前面有个private, 然后加上这个strong params method, 这个会store all our infor 并且只让开发者访问下面的method.e.g.:

private
def person_params
params.require(:person).permit(:name, :age)
end

这里我们是以persons Controller为例,we make a private person_params method. In the body of the method, we require the Model name (person), and permit the columns (name, age).现在任何时候我们想要person的信息,我们都引用为我们存储了信息的person_params method.

【好,这里的操作】In categories_controller.rb, beneath the end afterdef delete, declare aprivate method. Under the private, create acategory_params method for categories. Remember to requirecategory
and permit aname and thumburl. Useend to close it. Hit Run.

class CategoriesController < ApplicationController
def index
end def show
end def new
end def edit
end def delete
end #declare a private method
private
def category_params
params.require(:category).permit(:name, :thumburl)
end
end

上面用到了params.require,是一个验证method, 大意是只有name 和 thumburl可以被验证通过,存入model,详见:http://stackoverflow.com/questions/18424671/what-is-params-requireperson-permitname-age-doing-in-rails-4

---<2>---加入methods内容

我们来丰富Controller的methods内容:

**First, the index method. The index method takes every entry in our database and stores it as a variable.

If each record in our app is about person, the index method would show us all
persons
in our database. Just like a real index. It looks like this:

def index
@persons = Person.all
end

Here we take all persons, and store them in an instance variable @persons.

【操作】

在categories_controller.rb文件中:

  def index
@categories = Category.all
end

开始丰富下一个method之前,我们先来试一下index工作没有。



=====  接下来就不知所云  =====



在Rails App的Request-Response Cycle里,我们已知一个url请求来了要经过route分发到正确的Controller & View. 对于五个数据库操作的methods,我们都要有route and view 与之对应。



 Recall how we said Rails does some magic for us. It actually does two pieces of magic when we generate a Controller with methods!

a. It updates the routes file routes.rb with resources :categories. This shorthand will take care of our routes for the methods we will implement in Categories Controller.

b. It creates index.html.erb in the Views folder

When we generate a Controller with a given methods, it creates a route and View for us, magically. Otherwise, we have to do this manually.



【Instructions】

Check out routes.rb to see resources :categories. Then, in the browser window, visit localhost:8000/categories to see the index view Rails created.

**在config/routes.rb文件中,

Rails.application.routes.draw do
get '/' => 'pages#home' #这样写总算是让人有点明白了 resources :categories #这是一种方法,还有以下两种方法:
  #get '/categories' => 'categories#index'
  #get 'categories/index' #browser_url: http://localhost:8000/categories/index get 'categories/:id/delete' => 'categories#delete', :as => :categories_delete
end

**在index.html.erb文件中:

<h1>Categories#index</h1>
<p>Find me in app/views/categories/index.html.erb</p>

Rails建立了一个route and View for us, 但是是个空的文件,改变index.html.erb文件,让它看起来好点。index视图应该怎么样的?index method保存了数据库的所有条目,所以index 视图应该显示出所有条目。看个例子:

Say we have a persons index page want to show all persons in our collection.

We write:

--------------

<% @persons.each do |person| %>

<tr>

  <td><%= person.name %></td>

  <td><%= person.age %></td>

</tr>

<% end %>

--------------

Here we go through each person stored in @persons with an iterator and print out the attributes person.name and person.age.

然后把这个应用在index.html.erb的cagegory组里:

**index.html.erb文件:

<h1>Listing categories</h1>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Thumburl</th>
      <th colspan="3"></th>
    </tr>
  </thead>   <tbody>
    <% @categories.each do |category| %>
      <tr>
        <td><%= category.name %></td>
        <td><%= category.thumburl %></td>
        <td><%= link_to 'Show', category_path(category) %></td>
        <td><%= link_to 'Edit', edit_category_path(category) %></td>
        <td><%= link_to 'Destroy', category, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table> <br> <%= link_to 'New Category', new_category_path %>

此时再来访问localhost:8000/categories即可获得列表:

The index page we made has all the right information, but it didn't have the structure and style. We've added the supporting HTML code for the view.

文件和信息流程图如下,

但有几个疑问:

1. config/routes.rb文件中get 'categories/:id/delete' => 'categories#delete', :as => :categories_delete不能动,为啥?

2. routes.rb 与 Controller是怎么联系的?或者routes.rb, controller, view 三者是怎么联系?

3. index.html.erb文件中,



以下是加入了style效果的html:

<%= render 'shared/topnav' %>

<div class="categories">
<div class="container">
<div class="row">
<div class="col-md-2">
<h2>Categories</h2>
<p>Explore our latest categories from around the world.</p>
</div>
<div class="col-md-8">
<% @categories.in_groups_of(3).each do |categories| %>
<% categories.select! {|x| !x.nil?} %>
<div class='row'>
<% categories.each do |category| %>
<div class='col-md-4'>
<div class="thumbnail">
<img src= <%= category.thumburl %> >
<div class="caption">
<span class="listing-title"><%= category.name %></span>
<span><%= link_to "Edit", edit_category_path(category.id) %></span>
<span><%= link_to 'Show', category %></span>
<td><%= link_to 'Delete', categories_delete_path(:id => category.id) %></td>
</div>
</div>
</div>
<% end %>
</div>
<% end %> </div>
</div> </div>
</div> <table>
<thead>
<tr>
<th>Category name</th>
<th colspan="3"></th>
</tr>
</thead> <tbody>
<% @categories.each do |category| %>
<tr>
<td><%= category.name %></td>
<div class="thumbnail">
<img src= <%=category.thumburl %> >
<div>
<td><%= link_to 'Show', category %></td>
<td><%= link_to 'Edit', edit_category_path(category) %></td>
<td><%= link_to 'Delete', categories_delete_path(:id => category.id) %></td>
</tr>
<% end %>
</tbody>
</table>
<br> <%= link_to 'New Category', new_category_path %> <%= render 'shared/footer' %>



验证了。没搞懂。

** app/controllers/categories_controller.rb文件:

class CategoriesController < ApplicationController
def index
@categories = Category.all
end def show
end def new
end def edit
end def delete
end private
def category_params
params.require(:category).permit(:name, :thumburl)
end end

================

继续丰富我们的controller:

While index gave all categories, show allows us to access one category. This this is helpful when we want to show just one Category at a time in our Etsy app.

The show method works like this. we write:

def show
@category = Category.find(params[:id])
end

5.

Ruby学习笔记4: 动态web app的建立的更多相关文章

  1. Ruby学习笔记6: 动态web app的建立(3)--多Model之间的交互

    We first built a static site which displayed a static image using only a Controller and a View. This ...

  2. Ruby学习笔记5: 动态web app的建立 (2)

    上一节里,我们搭建了一个数据库的结构,并用index验证了request-response cycle,如下图: 1. Add show method into Controller 这一节,我们要继 ...

  3. JavaWeb学习笔记——开发动态WEB资源(一)Java程序向浏览器输出数据

    开发一个动态web资源,即开发一个Java程序向浏览器输出数据,需要完成以下2个步骤: 1.编写一个Java类,实现Servlet接口 开发一个动态web资源必须实现javax.servlet.Ser ...

  4. JavaWeb学习笔记——开发动态WEB资源(八)cookies和httpsession

    会话: cookies: (1)cookies是WEB服务器发送到浏览器的简短文本信息 (2)cookies可以禁用 httpsession: 一次会话是从你打开浏览器开始到你关闭浏览器结束 提供一种 ...

  5. JavaWeb学习笔记——开发动态WEB资源(六)ServletConfig和ServletContext

    1.只有在第一次请求服务器产生实例的时候才会调用init()方法,有一种办法能在服务器一启动的时候就加载init()方法. 即服务器启动即加载Servlet,且按数字大小顺序实例化Servlet. 方 ...

  6. JavaWeb学习笔记——开发动态WEB资源(五)servlet身份验证

    本工程的功能是实现Javaweb的servlet身份验证 一下是login.html文件中的代码 <!DOCTYPE html> <html> <head> < ...

  7. JavaWeb学习笔记——开发动态WEB资源(四)打印当前使用的是get方法

    该工程的名称是testhttp,功能是在页面中表格打印浏览过程中的相关头信息. 新建一个工程,然后在这个工程里面新建一个servlet,这样便可以省去编写web.xml的过程 以下是TestHttpS ...

  8. JavaWeb学习笔记——开发动态WEB资源(三)显示当前时间

    该工程的功能是实现在页面中显示当前的时间 以下的代码是HelloServlet.java中的代码 package helloapp2; import java.io.IOException; impo ...

  9. JavaWeb学习笔记——开发动态WEB资源(二)HelloWord

    该工程的功能是在页面上输出一段话 首先在src里面新建一个class,在interface里面添加javax.servlet.Servlet 以下是HelloServlet.java中的代码: pac ...

随机推荐

  1. Pandas的使用(2)

    Pandas的使用(2) 1.新建一个空的DataFrame数据类型 total_price = pd.DataFrame() #新建一个空的DataFrame 2.向空的DataFrame中逐行添加 ...

  2. EXPLAIN执行计划中要重点关注哪些要素

    MySQL的EXPLAIN当然和ORACLE的没法比,不过我们从它输出的结果中,也可以得到很多有用的信息. 总的来说,我们只需要关注结果中的几列: 列名 备注 type 本次查询表联接类型,从这里可以 ...

  3. 移动互联网终端的touch事件判断方向

    var pressX = 0, pressY = 0; document.body.addEventListener('touchmove', function(event) { // 如果这个元素的 ...

  4. OwnCloud 开源网盘

    https://www.getnas.com/freenas-owncloud/ FreeNAS 插件:OwnCloud 开源网盘 ownCloud 分为服务器端和客户端两个部分,服务器端可以在 Fr ...

  5. Maven Gradle 区别

    Maven面临的挑战 软件行业新旧交替的速度之快往往令人咂舌,不用多少时间,你就会发现曾经大红大紫的技术已经成为了昨日黄花,当然,Maven也不会例外.虽然目前它基本上是Java构建的事实标准,但我们 ...

  6. 让Netbeans 8.0 支持 Python 编程

    发布人 admin. 分类 Python, 技术手札 Netbeans版本:Netbeans 8.0 for PHP Python版本:python 2.7.8 1.添加插件更新中心 打开Netbea ...

  7. 利用curl 模拟多线程

    所谓多线程就是多个 程序同时运行,单线程:执行一段逻辑,等待完成后 在执行另外一个. 多线程:几个逻辑同时进行处理,不需要相互等待,提高了总的执行时间 接下来就用curl实现多线程 实现逻辑 1. f ...

  8. tomcat整体架构

    1.背景 Tomcat作为JavaWeb领域的Web容器,目前在我们淘宝也使用的也非常广泛,现在基本上所有线上业务系统都是部署在Tomcat上.为了对平时开发的Web系统有更深入的理解以及出于好奇心对 ...

  9. spring笔记-@Primary注解

    1.问题 当一个接口有2个不同实现时,使用@Autowired注解时会报org.springframework.beans.factory.NoUniqueBeanDefinitionExceptio ...

  10. [UE4]Actor的Destroyed事件