zoukankan      html  css  js  c++  java
  • 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.




  • 相关阅读:
    sabaki and leelazero
    apply current folder view to all folders
    string operation in powershell
    wirte function in powershell
    add environment path to powershell
    Module in powershell
    sql prompt
    vmware中鼠标在部分区域不能使用
    调整多个控件的dock的顺序
    行为型模型 策略模式
  • 原文地址:https://www.cnblogs.com/sonictl/p/6735561.html
Copyright © 2011-2022 走看看