CS计算机代考程序代写 SQL database Rapid Application Development

Rapid Application Development
COSC2675 2021 Week 6
A/Prof. Andy Song andy.song@rmit.edu.au
Last Week
• Rails Basics
• Rails philosophy
• Understand layouts **
• Adding images
• The layout method
• Template working with a layout
• Action Pack
• Model
• Controller
• Workingwithasimplewebform
A/Prof. Andy Song RMIT University 2021
2

Connect to a DB through a model
• Create a model $ rails generate model entry
Running via Spring preloader in process 11245
invoke active_record
create db/migrate/[Time Stamp]_create_entries.rb create app/models/entry.rb
invoke test_unit
create test/models/entry_test.rb
create test/fixtures/entries.yml
• Contentofdb/migrate/[TimeStamp]_create_entries.rb:
class CreateEntries < ActiveRecord::Migration[5.2] def change end end end create_table :entries do |t| t.timestamps #what is this? A/Prof. Andy Song RMIT University 2021 3 The migrate rb • Atablewithpluralformofthemodelnameiscreated • Sotablebooksformodelbook,entriesforentry,micefor mouse, waters for water, sheep for sheep, gooses for goose, men for man, wolves for wolf, oxen for ox, children for child. • Methodchangereplacedself.upandself.downforundo. • Add one line: class CreateEntries < ActiveRecord::Migration[5.0] def change create_table :entries do |t| t.string :name t.timestamps end end end • Thislineistocreateacolumnofstringtostorenames. A/Prof. Andy Song RMIT University 2021 4 Migration • Tomakethelastchangetakeeffect,run$railsdb:migrate • Migrations are a convenient way to change your database schema over time. • EachmigrationcanbeconsideredasanewversionoftheDB • Aschemastartsoffwithnothinginit. • Eachmigrationmodifiesittoaddorremovetables,columns or entries. • It is managed by ActiveRecord which controls the versions. • You can $ rails db:migrate:redo STEP=3 $ rails db:rollback STEP=3 $ rails db:migarte VERSION=20210412120000 A/Prof. Andy Song RMIT University 2021 5 The skinny model • Open app/models/entry.rb, we see simply class Entry < ApplicationRecord end • BeforeRails5.0,amodelisadirectsubclassofActiveRecord. • Now it is through ApplicationRecord, open app/models/application_record.rb class ApplicationRecord < ActiveRecord::Base self.abstract_class = true end • It tries to be an abstract class although Ruby does not have abstract method and class in its syntax. A/Prof. Andy Song RMIT University 2021 6 The controller • Edit the controller app/controllers/entries_controller.rb class EntriesController < ApplicationController def sign_in @name = params[:visitor_name] @entry = Entry.create({:name => @name})
end
• Thislineeffectivelydoesthreetasksforeachentry @entry = Entry.new
@entry.name = @name # @name is from the form
@entry.save
• Name@entryisnotspecial,canbe@data,@info,@fooetc.
• The new version is better as its avoids empty entries and read all entries.
unless @name.blank?
@entry = Entry.create({:name => @name})
end
@entries = Entry.all
A/Prof. Andy Song RMIT University 2021
7

Then the view
Edit the view: app/views/entries/sign_in.html.erb

Hello <%= @name %>

<%= form_tag action: 'sign_in' do %>

Enter your name:
<%= text_field_tag 'visitor_name', @name %>

<%= submit_tag 'Sign in' %>
<% end %>

There are <%= @entries.size %> previous visitors

    <% @entries.each do |entry| %>

  • <%= entry.name %>
  • <% end %>

A/Prof. Andy Song RMIT University 2021
8

Now you should see
A/Prof. Andy Song RMIT University 2021
9
Take a look at the console
Started POST “/entries/sign_in” for [IP] at [TimeStamp] Processing by EntriesController#sign_in as HTML
Parameters: {“utf8″=>”􏰀”, “authenticity_token”=>”pw..[cut]…==”, “visitor_name”=>”Louise”, “commit”=>”Sign in”}
(0.1ms) begin transaction
SQL (1.1ms) INSERT INTO “entries” (“name”, “created_at”, “updated_at”) VALUES (?, ?, ?) [[“name”, “Louise”], [“created_at”, [TimeStamp] UTC], [“updated_at”, [TimeStamp] UTC]]
(15.0ms) commit transaction
Rendering entries/sign_in.html.erb within layouts/application
(0.3ms) SELECT COUNT(*) FROM “entries”
Entry Load (0.2ms) SELECT “entries”.* FROM “entries”
Rendered entries/sign_in.html.erb within layouts/application (153.6ms)
Completed 200 OK in 196ms (Views: 175.3ms | ActiveRecord: 16.8ms)
Rails is working hard behind the scene!
A/Prof. Andy Song RMIT University 2021
10

Model Methods
• Entry.all, Entry.find(1).id
• Entry.first, Entry.last.name
• Entry.where(name: “Alex”)
• Entry.limit 3, Entry.limt(3).offset(2)
• Entry.order(:name) # and many DB query methods!
• The Rails documentation also has some http://guides.rubyonrails.org/active_record_querying.html
• ThesemethodsarefromActiveRecord.Seedetailsofthese methods on Rails API: api.rubyonrails.org
• These methods can also be called in Rails console (>rails c)!
>>Entry.find(1)
Entry Load (0.3ms) SELECT “entries”.* FROM “entries” WHERE
“entries”.”id” = ? LIMIT ? [[“id”, 1], [“LIMIT”, 1]]
=> #
A/Prof. Andy Song RMIT University 2021
11
Scaffolding a model
• ScaffoldingisoneofthemaincontributingfactorsforrapidRails development.
• Let us try that on a new guest book application, say guestbook_2 $ rails generate scaffold Person name:string
$ rails generate controller entries sign_in [no scaffolding]
• Itgeneratesscaffolding,aroundmodelPersonwithoneattribute
name. Note the table name is people not persons.
• Try to view it on localhost:3000/people What do you see?
• Tryagainafterrunning$railsdb:migrate A/Prof. Andy Song RMIT University 2021
12

What happened in scaffolding
• ScaffoldingallowsRailscreatealistofcomponents − a model with tests
− a data migration to establish the tables for the model − a new route to map user requests to the controller
− a controller to connect different components and pass data − four views (index, edit, show and new) and a partial form − tests for the controller
− an empty file for helper methods
− a CoffeeScript file for scripting the pages − Stylesheets for all of those views
A/Prof. Andy Song RMIT University 2021
13
What happened in scaffolding
• config/routes.rb
Rails.application.routes.draw do
resources :people
end
• Not much in model app/models/person.rb class Person < ApplicationRecord end • 70+ lines added automatically to the controller app/controllers/people_controller.rb • The view is a bit complicated. A/Prof. Andy Song RMIT University 2021 14 Interacting with the site Notice the URL of each page? A/Prof. Andy Song RMIT University 2021 15 RESTful Rails • TheURLsaremeaningful: .../people/edit .../people/new .../people, .../people/1, .../people/4 • The actions are visible through these URLs • You can bookmark a data resource say .../people/4 or an action .../people/2/edit • Adminscanmanagewebtrafficwithoutworryingabout disrupting the application. • AneatfitwithRails’MVCarchitecture. • EasiertobehaveRESTfully. A/Prof. Andy Song RMIT University 2021 16 REST • REpresentational State Transfer, an architecture defined by Roy Fielding in his 2000 PhD thesis at UC Irvine. • Allows access text-based web resources using a uniform and pre- defined set of stateless operations. • Does not create new techniques. • Based on HTTP request, GET = read, POST = write, DELETE = destroy, PUT = update etc. • Supports CRUD (create, read, update, destroy) which are common persistent resource operations, often seen in DB, Web, Files. • Simpler than SOAP (Simple Object Access Protocol, XML based) and WSDL ( Web Services Description Language, XML based) • Other properties: good scalability, performance, visibility, portability, modifiability, reliability. A/Prof. Andy Song RMIT University 2021 17 RESTful controller • Requires a shift in the way developers think about controllers and writing web applications. • Controllers can be verbs. Each controller implements the same verbs. • The controller becomes a standardized connection to data model. • URLs connect the client to a resource (noun) on the server in predictable ways. • Based on HTTP request, GET = read, POST = write, DELETE = destroy, PUT = update etc. • ItisnotonlyforHTML,butcanbeusedonresourcesfor JSON, Ajax. A/Prof. Andy Song RMIT University 2021 18 RESTful Routes • Remember what is in config/routes resources :people • Ifwerunthiscommand$railsroutes Prefix Verb people GET URI Pattern Controller#Action people#index people#create people#new people#edit people#show people#update people#update people#destroy new_person GET edit_person GET person GET /people/new(.:format) /people/:id/edit(.:format) /people/:id(.:format) /people(.:format) POST /people(.:format) PATCH /people/:id(.:format) PUT /people/:id(.:format) DELETE /people/:id(.:format) • ResourcesgiveasetofRESTfulURLs. • HTTP requests are mapped to actions. Meaning a URL such as GET /people/1/edit is processed by people#edit A/Prof. Andy Song RMIT University 2021 19 RESTful Routes (Learning Rails 5, Mark Locklear Eric Gruber) 20 A/Prof. Andy Song RMIT University 2021 Can work on JSON files (Learning Rails 5, Mark Locklear Eric Gruber) A/Prof. Andy Song RMIT University 2021 21 Can work on JSON files • You can try in a browser localhost:3000/people.json If we run this command $ rails routes • TheoutputofJSONfilescanbeviewedatthebrowser [{"id":1,"name":"Alexei","created_at":”[TimeStamp]", "updated_at":"[TimeStamp]","url":" localhost:3000/people/1.json"}, {"id":2,"name":"Ali","created_at":"[TimeStamp]", "updated_at":"[TimeStamp]","url":" localhost:3000/people/2.json"}, {"id”:4,"name":"Louise","created_at":"[TimeStamp]", "updated_at":"[TimeStamp]","url":" localhost:3000/people/4.json"}] • HTTP requests are mapped to actions. Meaning a URL such as GET /people/1/edit is processed by people#edit A/Prof. Andy Song RMIT University 2021 22 Specify a layout A/Prof. Andy Song RMIT University 2021 23 A/Prof. Andy Song RMIT University 2021 24 RESTful Methods • before_action :set_person, only: [:show, :edit, :update, :destroy] • The private callback set_person • The new method does not touch the database, only in memory. • The controller simply pass the model to the view new.html.erb, without worrying about the schema etc. • Person.new(person_params) is another callback • respond_to method is from ActionController, allows responses in various formats on the same data. A/Prof. Andy Song RMIT University 2021 25 Multiple Tables • Working with multiple tables is made easy by Rails. • Every model maps to a table. • The relationships between tables are managed as relationships between models. • Scaffoldingwillbehelpful.Howevertherearequitesome coding need to done manually. • Thetaskwillbemuchmoredifficultifyouareretrofittingan existing database (not generated by Rails) rather than creating a fresh new database in Rails. A/Prof. Andy Song RMIT University 2021 26 A Students Application • Create a new application called students : $ rails generate scaffold student given_name:string middle_name:string family_name:string date_of_birth:date grade_point_average:decimal start_date:date $ rails generate scaffold award name:string year:integer student_id:integer Two models have been created. Rails doesn’t know they are connected yet. Model award has a student_id field. A/Prof. Andy Song RMIT University 2021 27 A Students Application • Open app/models/student.rb and add # a student can have many awards has_many :awards • Open app/models/award.rb and add # every award is linked to a student, through student_id belongs_to :student • has_many and belongs_to are just two methods • Theyspecifytheassociationbetweenmodels • Similar methods include: has_one has_and_belongs_to_many A/Prof. Andy Song RMIT University 2021 28 Association methods • Detailsofhas_manyandbelongs_tocanbeseenintheRailsAPI http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#meth od-i-has_many http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#meth od-i-belongs_to • Theyareclassmethodsfrom ActiveRecord::Associations::ClassMethods • Their method signatures are: has_many(name, scope = nil, options = {}, &extension) belongs_to(name, scope = nil, options = {}) A/Prof. Andy Song RMIT University 2021 29 Association methods has_many :friends, -> { where(author_id: 1) },
through: :societies, source: :member, do
def find_or_create_by_name(name)
first_name, last_name = name.split(” “, 2) find_or_create_by(first_name: first_name, last_name: last_name)
end end
belongs_to :firm, foreign_key: “client_of”
belongs_to :person, primary_key: “name”, foreign_key: “person_name” belongs_to :author, class_name: “Person”, foreign_key: “author_id” belongs_to :project, -> { readonly }
belongs_to :attachable, polymorphic: true
belongs_to :valid_coupon, ->(o) { where “discounts > ?”, o.payments_count },
class_name: “Coupon”, foreign_key: “coupon_id”
A/Prof. Andy Song RMIT University 2021
30

Run the application
• Through these association methods Rails knows the connection between models.
• Rails does not add automatic checking or validation to ensure that the relationships would work.
• E.g.doesnotrequireavalidstudentIDforeveryaward.
• Although that can achieved using scope, option
• Now you can start the Students Application $ rails db:migrate
$ rails s
• Create new students at localhost:3000/students/new
A/Prof. Andy Song RMIT University 2021
31
Adding new records
How about create an award at
localhost:3000/awards/new
A/Prof. Andy Song RMIT University 2021
32

Add an Award
• Aselectfieldsoundslikeagoodideatosolvetheproblem.
• Editthestudentfieldinpartialapp/views/awards/_form.html.erb
• Remove <%= form.number_field :student_id, id: :award_student_id %> and change to
< div class =" field" >
<%= form.label :student_id %>
<%= form.select :student_id, Student.all.order(:family_name, :given_name).collect {|s| [( s.given_name + " " + s.family_name), s.id]}%>

• select method creates the form, all method lists all student record, order method sorts all records by family names then give names, collect similar to each is another array method to run the block on each element but returns the new array.
A/Prof. Andy Song RMIT University 2021
33
Adding a new award
Now view localhost:3000/awards/new


Assume we have created Alex, Anto and Matt beforehand.
A/Prof. Andy Song RMIT University 2021
34

Improve the view
• Theforminpreviousslidesubmitthefirststudentas“1”
• To replace with a proper name, update both
app/views/awards/show.html.erb and app/views/awards/index.html.erb
• Replace <%= @award.student_id %> to <%= @award.student.given_name %> <%= @award.student.family_name %>
and <%= award.student_id %> to <%= award.student.given_name %> <%= award.student.family_name %>
• Wheredoesthisstudentmethodinawardcomefrom?
• Thanks the belongs_to method. Now we have access to
given_name and family_name methods. A/Prof. Andy Song RMIT University 2021
35
Further improve the view
[@]award.student.given_name, [@]award.student.family_name were repeated in the previous slides. Remember DRY?
• Letdefineanamemethodinapp/models/student.rb
def name
given_name + ” ” + family_name
end
• Use the new version
<%= @award.student.name %> in app/views/awards/show.html.erb, <%= award.student.name %> in app/views/awards/index.html.erb
• and <%= form.select :student_id, Student.all.collect {|s| [s.name, s.id]} %> in app/views/awards/_form.html.erb
• Thenamemethodisoftencalledanattributeonthemodel. If you need to assign values to it, then define name= method.
36
A/Prof. Andy Song RMIT University 2021

An award record shows student
Now view a record as localhost:3000/awards/1
The index action should also show names localhost:3000/awards 37
A/Prof. Andy Song RMIT University 2021
What if a record is deleted
Let’s delete Alex from the previous example
Oops! That messed up the awards page localhost:3000/awards You can disable the name method in awards’s index (%#), delete Alex’s award, put back
thenamemethod. Thentheapplicationwillbebacktonormal. A/Prof. Andy Song RMIT University 2021
38

Connecting Students to Awards
• Orphaned record: when Alex was deleted, his award still remains.
• Rails did not notice the deletion.
• We need to keep award records in sync with student records.
• It is actually easy. Just update app/models/student.rb
has_many :awards
has_many :awards, dependent: :destroy
• Once a student record is deleted, then all the awards records of that student will also disappear.
• Warning:thisdeletiondoesnotaskforconfirmation. A/Prof. Andy Song RMIT University 2021
39

The dependent option
Rails API Doc explains
“ Controls what happens to the associated objects when their owner is destroyed. Note that these are implemented as callbacks, and Rails executes callbacks in order. Therefore, other similar callbacks may affect the :dependent behavior, and the :dependent behavior may affect other callbacks.”
• Optionsfordependentare:
− :destroy
− :delete_all
− :nullify
− :restrict_with_exception
− :restrict_with_error
− Ifusingwiththe:throughoption,theassociationonthejoinmodelmust be a belong_to, and the records which get deleted are the join records, rather than the associated records.
A/Prof. Andy Song RMIT University 2021
40

Counting Awards
• Howtoaddanewcolumnforstudentstoshowthetotal number of awards that each student has?
• Obviouslyweneedtochangetheviewofindex app/views/students/in⁠dex.html.erb
• Add

Awards

in table head

after Start date
• Add

<%= student.awards.count %>

also after start_date
A/Prof. Andy Song RMIT University 2021
41
List the awards for each student
• Add a table in app/views/students/show.html.erb

Awards

<% @student.awards.each do | award | %>

<% end %>

Name Year Student
<%= award.name %> <%= award.year %> <%= award.student.name %>

A/Prof. Andy Song RMIT University 2021
42

Summary
• Model
• Controller
• DB migration
• Rails console
• REST
• RESTfulresources(withdifferentformats)
• RESTfulmethods
• Multiple tables
• Association methods
• Dependent tables
A/Prof. Andy Song RMIT University 2021
43