Transcript The MVC

Web Science Stream
Models, Views and
Controllers
Dr Alexiei Dingli
1
Case Study: digg
2
Creating our shovell application
rails shovell
3
Generating our model
• To generate a new data model for our application we’ll use the
comand below
• Our Story model will get two attributes
– Name
– Link
• String is a type which holds up to 255 alphanumeric
characters
• cd shovell
• ruby script/generate model Story name:string link:string
4
The output should be ...
•
•
•
•
•
•
•
•
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/story.rb
create test/unit/story_test.rb
create test/fixtures/stories.yml
create db/migrate
create db/migrate/20091019052909_create_stories.rb
5
Let’s look at the output
• story.rb
– In the app/model
– Creates a blank ActiveRecord
• story_test.rb
– Automatically generated unit testing
• stories.yml
– Helps our unit testing and is called a Fixture
– Fixtures are files containing simple data for unit testing purposes
• 20091019052909_create_stories.rb
– A migration file
6
YAML
• Lightweight format to represent data
• Has the .yml extension
• Have a look at the test/fixtures/stories.yml
7
stories.yml
• # Read about fixtures at
http://ar.rubyonrails.org/classes/Fixtures.html
• one:
•
name: MyString
•
link: MyString
• two:
•
name: MyString
•
link: MyString
8
stories.yml
• # Read about fixtures at
http://ar.rubyonrails.org/classes/Fixtures.html
• one:
•
name: My web site
•
link: http://abc.net
• two:
•
name: Other web site
•
link: http://www.theotherwebsite.com
9
I’m going to Migrate!
• Migration files
– Used to make modifications to the database
schema
– All through Ruby code
– No SQL needed
– Files are numbered so they can be executed
sequentially
– They are executed in order
10
– Located in the db/migrate dir
20091019052909_create_stories.rb
• class CreateStories < ActiveRecord::Migration
•
def self.up
•
create_table :stories do |t|
•
t.string :name
•
t.string :link
•
•
•
t.timestamps
end
end
•
def self.down
•
drop_table :stories
•
end
• end
11
Let’s do a small modification
• Change
– create_table :stories do |t|
• To
– create_table :stories, :force =>true do |t|
• Useful if we already have some table
structures defined in the database
12
Let’s make our migrate
• rake is based upon the C make tool
• Very versatile and allows us to do a
number of things ...
• Try
– rake –T
• In our example we’ll make the migration by
invoking
13
– rake db:migrate
rake db:migrate
1. Checks the database for the most recent
migration
2. Steps through the migrations that have
not been applied
3. For each migration execute the up
method
14
The output
== CreateStories: migrating ==================
-- create_table(:stories)
-> 0.0040s
== CreateStories: migrated (0.0050s) =========
• If it is successful we will find a stories table in our
shovell database
15
Rolling back
• rake db:migrate version=n
• Eg: undo all the tables in the database by
invoking:
– rake db:migrate version=0
16
Playing with the data
• Open a rails console
– ruby script/console
17
Creating our first record
•
•
•
•
s = Story.new
s.name = “My new website”
s.link = “http://abc.net”
s.save
• The end result should be
• => true
18
More on records ...
• To see the record id
– s.id
• To check if its a new record
– s.new_record?
• To check the number of Stories in the DB
– Story.count
• Another way of creating records
– Story.create(
:name => ‘Abc’,
:link => ‘http://www.mysite2.com’)
19
Retrieving records
• Story.find(2)
• Story.find(:all)
• Story.find(:all).last
• Story.find(:first, :order => ‘id DESC’)
20
Dynamic finders ...
• Story.find_by_name(‘Abc’)
• How would we find the link ‘http://abc.net’?
• Try it ...
21
Let’s update
• s = Story.find_by_name(‘Abc’)
• s.name = ‘Abcd’
• s.save
22
Let’s update and save in
just one step
• s = Story.find_by_name(‘Abcd’)
• s.update_attribute :name. ‘Abcde’
23
Bye Bye records
• s.destroy
• Try to find the record ... what’s the
message?
24
What about SQL?
• Have a look at
– log/development.log
– CREATE TABLE "stories" ("id" INTEGER
PRIMARY KEY AUTOINCREMENT NOT
NULL, "name" varchar(255), "link"
varchar(255), "created_at" datetime,
"updated_at" datetime
25
Generating our first controller!
• ruby script/generate controller Stories
index
26
The output
•
•
•
•
•
•
•
•
•
•
exists
exists
create
exists
create
create
create
create
create
create
app/controllers/
app/helpers/
app/views/stories
test/functional/
test/unit/helpers/
app/controllers/stories_controller.rb
test/functional/stories_controller_test.rb
app/helpers/stories_helper.rb
test/unit/helpers/stories_helper_test.rb
app/views/stories/index.html.erb
27
Explaining the output
• First it generates a number of folders (unless they
have been created already)
• StoriesController
– Has defined the index method
• stories_controller_test.rb
– Will hold the test functions
• stories_helper.rb
– Class to help the controller
• Index.html.erb
– One of the views which will be our initial template
28
Let’s see what we have so far ...
• Start a server
– ruby script/server
• Goto
– http://127.0.0.1:3000/stories
29
Creating views
Two ways ... With or Without scaffolding!
30
What is scaffolding?
• A powerful feature of rails
• Quickly creates a web interface for
interacting with your model
• Provides an easy way to add, manipulate
and delete records
• Scaffold generates a model, controller,
actions and other templates
31
Limitations of Scaffold
• Designed for quick interaction only
• Not intended as a fully automateed web
site generator
• It can’t cope with associations
(relationships) between objects
32
Let’s scaffold!
• ruby script/generate scaffold Story name:String link:String
33
Let’s see what we have so far ...
• Start a server
– ruby script/server
• Goto
– http://127.0.0.1:3000/stories
34
Script/generate
• Scaffold is essentially a script that we
invoke using script/generate
• The nice thing about script/generate is that
there exists a script/destroy using exactly
the same arguments
• So let’s destroy the scaffold
– ruby script/destroy scaffold Story name:String
link:String
35
Let’s see what we have so far ...
• Start a server
– ruby script/server
• Goto
– http://127.0.0.1:3000/stories
36
Ohh No!! We lost everything!!
• ruby script/generate model Story name:string link:string
• ruby script/generate controller Stories index
37
Let’s see what we have so far ...
• Start a server
– ruby script/server
• Goto
– http://127.0.0.1:3000/stories
38
Views
• app/views/stories
– Only index.html.erb so far
– Generated as a static page
– Let’s add some dynamic information
• Insert
– <%= Time.now %>
39
Let’s see what we have so far ...
• Start a server
– ruby script/server
• Goto
– http://127.0.0.1:3000/stories
40
Problems!
• We shouldn’t be including ruby code
directly in the view
• Ideally we keep them separated so ...
– In the /app/controllers/stories_controller.rb
• In the def index add
– @current_time = Time.now
– In the app/views/stories/index.html.erb replace
the previous code with
– <%= @current_time %>
– Try it out!
41
Let’s do something more useful
• In the controller
/app/controllers/stories_controller.rb
– In the def index, remove what we just wrote
and write
• @story = Story.find(:first, :order => ‘RANDOM()’)
– In the app/views/stories/index.html.erb replace
the previous code with
– A random link: <%= link_to @story.name, @story.link %>
42
Let’s see what we have so far ...
• Start a server
– ruby script/server
• Goto
– http://127.0.0.1:3000/stories
43
Didn’t work?
• Why not add some data and try again?
•
•
•
•
•
•
ruby script/console
Loading development environment (Rails 2.3.2)
>> s = Story.new
>> s.name = "ABC"
>> s.link = "http://aaa.com"
>> s.save
44
Questions?
45