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


    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.




  • 相关阅读:
    论工作动力的来源是什么?答案是来自于实现自己的梦想
    向梦想者致敬
    内置函数,递归函数,模块与包,开发目录规范
    迭代器,生成器
    闭包函数,装饰器,语法糖
    函数对象,名称空间及查找,作用域
    函数调用与参数
    字符编码
    文件处理
    python 11.5数据类型及常用方法
  • 原文地址:https://www.cnblogs.com/sonictl/p/6735561.html
Copyright © 2020-2023  润新知