程序代写代做代考 database WDE-Slides-11.pptx

WDE-Slides-11.pptx

Web System Development with
Ruby on Rails

Day 11(8/Dec/2013)
Project: mini twitter site
Face and ‘Follow’ table

Face table for users
p  Class Name: Face
p  Table Name: faces (plural)
p  1 to 1 relation with users table,

p  User has_one :face
p  Face belongs_to :user

p  Via user.face, if related link from face is
nil, display app/assets/images/
default_face.png file (default icon).

Structure of Face Class
Face Classのフィールド:
user_id, integer (index to User)
name, string (File Name)
content_type, string (MIME type name)
content, blob (content of image files)

Generation of Face Class
Type the following command in 1 line;

rails generate model Face user_id:integer
name:string content_type:string
content:binary

Then, generate the database.
rake db:migrate

Setting up Relations
Add
belongs_to :user

in app/models/face.rb, then add
has_one :face

in app/models/user.rb.

Registration of faces
To register faces, we generate faces

controller which have register action.
rails generate controller faces register

views/faces/register.html.erb

Register Face Photo

<%= form_for @face, :url => “/faces/update”,

:html => {:multipart => true}, :method => :put do %>

User: <%= @user.handle %>

Face Photo:
<%= file_field :file, :upload %>
<%= submit_tag "Update" %>

<% end %>

controllers/faces_controller.rb
Prepare register method, and update method.

# GET /faces/register
# GET /faces/register.json
def register
@face = Face.new
@user = User.find( current_user.id )
end

Update method
# PUT /faces/update
# PUT /faces/update.json
def update
@face = Face.find_by_user_id( current_user.id )
@face.destroy if @face
@user = User.find( current_user.id )
if params[:file]
@file = params[:file][:upload]
if @file && @file.respond_to?(:original_filename)
face_params = {
:user_id => @user.id,
:name => @file.original_filename,
:content_type => @file.content_type,
:content => @file.read
}
@face = Face.new( face_params )
end
end
if @face.save
respond_to do |format|
format.html { redirect_to edit_user_path( :id => current_user.id ),
:notice => ‘Face photo was successfully uploaded.’ }
format.json { render @user, status: :created, location: @user }
end
else
respond_to do |format|
format.html { render action: “register”, :alert => ‘Failed to register face photo.’ }
format.json { render json: @faces.errors, status: :unprocessable_entity }
end
end
end

Update Method
If any ‘face’ record had been already

registered, destroy the record, then
retrieve the new File parameter to register
new face upload.

Update = destroy and newly register.
If succeed, redirect to user registration

view.

Update method

File action in Chirps_controller
Add face image transfer action, when chirps are

displayed.

def face
face = Face.find( params[:id] )
send_data face.content, :filename => face.name,

:type=>face.content_type
end

config/routes.rb
To register and display, add two routings.
get “chirps/face” => “chirps#face”
put “faces/update” => “faces#update”

The following line should have been
generated by the generator.
put “faces/register”

Prepare default face file
Move ‘default_face.png’ file to app/assets/

images

Index of Chirps
Add Face photo display part.

<% if chirp.user.face %>

<% face = chirp.user.face %>

<% if face.content_type =~ /^image\/.*?(png|jpeg|gif)$/ %>

<%= image_tag url_for({:action => ‘face’, :id=> face.id,

:filename => face.name}), :alt => face.name

%>

<% else %>

<%= image_tag 'default_face.png', :alt => ‘No Photo’ %>

<% end %>

<% else %>

<%= image_tag 'default_face.png', :alt => ‘No Photo’ %>

<% end %>

Index of Chirps

Registration of Face
http://127.0.0.1:3000/faces/register
If you think you need to add link to this

path, try it by yourself.

Registration of Face
Now you should have Face photo (of the

twitter owner,) and the photo for tweets.

Arrange the links
Screen link is not well arranged. So, let us re-

arrange the screen links.

[Root view] ‘List of Chirps’
à Sign out:
à Edit your info

à Back(to ‘List of chirps’)
à Upload your photo

à Back(to ‘Edit info’)
à Change Password

à Back(to ‘List of chirps’)

app/views/chirps/index.html.erb
Arrange the top right index;
<% if current_user %>

Hello, <%= current_user.email %>

<%= link_to('Sign out', destroy_user_session_path, :method => :delete) %>

<%= link_to 'Edit your info', edit_user_path( :id => current_user.id ) %>

<%= link_to 'Change Password', edit_user_registration_path %>

<% end %>

after ‘Edit your info’ path
This view is in the file app/views/users/

edit.html.erb.
So we need to arrange ‘Back’ link from
<%= link_to 'Back', users_path %>
To
<%= link_to 'Back', chirps_path %>
Also in the file app/views/users/

show.html.erb.

Link: edit user à upload face photo
[Root view] ‘List of Chirps’

à Edit your info
à Upload your photo
à Back(to ‘Edit info’)

Now modify this views link;
1)  hand @face info link to view/users/edit.html.erb
2)  after uploading file, link back to edit users.
3)  confirm uploaded face in users/show.html.erb

1) Face photo upload in edit users
Add the following in app/views/users/

_form.html.erb


<%= form_for @face, :url => “/faces/update”,

:html => {:multipart => true}, :method => :put do %>

Face Photo:

<%= file_field :file, :upload %>

<%= submit_tag "Upload Photo" %>

<% end %>

app/views/users/_form.html.erb

Users controller, edit action
So that face could be registered, @face

should be given for ‘edit’ template;
# GET /users/1/edit
def edit
if @user.face
@face = Face.find(@user.face.id)
else
@face = Face.new
end
end

Users controller, edit action

2) After uploading file, link back
Check the faces_controller# update method;
It already has link back to edit user path.

3) Confirm uploaded face
Add users/face path to config/routes.rb
get “users/face” => “users#face”

Then add face method to users_controller

Add face in users/show.html.erb

<% if @user.face %>
Your face photo:
<% face = @user.face %>
<% if face.content_type =~ /^image\/.*?(png|jpeg|gif)$/ %>
<%= image_tag url_for({:action => ‘face’, :id=> face.id,
:filename => face.name}), :alt => face.name %>
<% end %>
<% else %>
<%= image_tag 'default_face.png', :alt => ‘No Photo’ %>
<% end %>

app/views/users/show.html.erb

Arranged Top chirps screen

Remove timestamp input;
Chirped_at timestamp should be given by

the system, so remove the input from
_form, and give Time.now in new method.

:chirped_at => Time.now

Tweets without photo
Now controller does not save tweets without photo.

Modify this part so that the system accept the
tweets without photo;

Chirps_controller.rb ‘else’ for ‘if params[:chirp]
[:photo]’

Also, when update, ‘user_id’, ‘chirped_at time

stamps’ should not be updated.

Chrips controller, create action
else

@chirp = Chirp.new( chirp_params )

@chirp.user_id = current_user.id

@chirp.chirped_at = Time.now

respond_to do |format|

if @chirp.save

format.html { redirect_to @chirp, notice: ‘Chirp was successfully created.’ }

format.json { render :show, status: :created, location: @chirp }

else

format.html { render :new }

format.json { render json: @chirp.errors, status: :unprocessable_entity }

end

end

end

Chirps Controller, create action

Chirps controller, update action
# PATCH/PUT /chirps/1
# PATCH/PUT /chirps/1.json
def update
if params[:chirp][:photo]
@file = params[:chirp][:photo]
@stat = @file.tempfile.stat
p “chirped_at:”
p params[:chirp][:chirped_at]
respond_to do |format|
if @chirp.update_attributes(
:chirp => params[:chirp][:chirp],
:file_name => @file.original_filename,
:file_type => @file.content_type,
:photo => @file.read,
)
format.html { redirect_to @chirp, notice: ‘Chirp was successfully updated.’ }
format.json { render :show, status: :ok, location: @chirp }
else
format.html { render :edit }
format.json { render json: @chirp.errors, status: :unprocessable_entity }
end
end
else
respond_to do |format|
if @chirp.update_attributes(
:chirp => params[:chirp][:chirp],
)
format.html { redirect_to @chirp, notice: ‘Chirp was successfully updated.’ }
format.json { render :show, status: :ok, location: @chirp }
else
format.html { render :edit }
format.json { render json: @chirp.errors, status: :unprocessable_entity }
end
end
end
end

Chirps controller, update action

Now today’s next topics: Follow

My Twitter
We have introduced face photo to ‘my twitter,’ for

my case, “Chirpy” WEB site.
My lecture slides only covered the basic structure of

the project. I hope you extend the previous
lecture slides to realize the following features/
functions;

(1) Internationalization,
(2) Screen Division/right, top bar and footer,
(3) Top banner image display, and such.

Today’s Next Topics
Today, we will add the following features;

“Follows” table, and list only followers
messages.

Follows Table

The structure is simple.
User → Follow table (one to many)
Follow Class

integer user_id Follower’s id
integer to_id Whom followed

rails generate model follow user_id:integer

to_id:integer

Setting up Relations for Follows
Add
in models/follow.rb 
belongs_to :user

in models/user.rb
has_many :follows

Make Controller
Do not forget migration,
rake db:migrate

Now we show “all” users list, and show
follow / not follow button to the list, and
then reflect this “follow/not follow”
selection.

First, make list view
rails generate controller follows list

Generation of Controller

List method of Follows controller

class FollowsController < ApplicationController def list @users = User.all @users -= [current_user] end end Access Controller So that always ‘Logged in users’ could tweet and follow, to avoid ‘current_user is nil,’ add the following, as is in the chirps_controller.rb; before_filter :authenticate_user! In both faces_controller.rb, and follows_controller.rb. Views/follows/list.html.erb

Follows#list

<% @users.each do |user| %>

<% end %>

<% if user.face %>
<% if user.face.content_type =~ /^image¥/.*?(png|jpeg|gif)$/ %>
<%= image_tag url_for({:controller => ‘chirps’, :action => ‘face’, :id=> user.face.id,
:filename => user.face.name}), :alt => user.face.name
%>
<% else %>
<%= image_tag 'default_face.png', :alt => user.face.name %>
<% end %>
<% else %>
<%= image_tag 'default_face.png', :alt => ‘No Name’ %>
<% end %>
<%= user.handle %> <%= user.email %>

Views/follows/list.html.erb
Show all users except for self

Users display except for self

Add follows information to list
Add the following one line in the list method

of follows_controller;

@follows = Follow.where( user_id: current_user.id )

Add Follow buttons
Add the following in the views/follows/

list.html.erb, in the table.

<% if @follows && (follow = @follows.find {|follow| follow.to_id == user.id }) %>
<%= form_tag "/follows/cancel/"+follow.id.to_s, :method => ‘put’ do %>
<%= submit_tag "Stop Follow", :name => “Cancel” %>
<% end %>
<% else %>
<%= form_tag "/follows/follow/"+user.id.to_s, :method => ‘put’ do %>
<%= submit_tag "Follow", :name => “Follow” %>
<% end %>
<% end %>

Config/routes.rb
Add two paths of /follows/follow, and /

follows/cancel
put “follows/follow/:id” => “follows#follow”, :as =>

‘follows_follow’
put “follows/cancel/:id” => “follows#cancel”, :as =>

‘follows_cancel’

Method for when “Followed”
# put /follows/follow
# put /follows/follow.json
def follow
follow_params = {
:to_id => params[:id],
:user_id => current_user.id
}
@follow = Follow.new( follow_params )

respond_to do |format|
if @follow.save
format.html { redirect_to follows_list_path }
format.json { render :json => @follow }
else
format.html { render action: “list”, :alert => ‘Failed to follow.’ }
format.json { render json: @follow.errors }
end
end
end

Method for when “Followed”

Method for when “Cancelled”
# put /follows/cancel
# put /follows/cancel.json
def cancel
@follow = Follow.find_by_id( params[:id] )
@follow.destroy
redirect_to follows_list_path
end

Test run for Follows/list
Now you would have the following view, to

switch follow/stop follow selection.

Choose the followers to show chirps
Modify index action in chirps controller from
def index
@chirps = Chirp.all
end

to the following;
@follows = Follow.find_all_by_user_id( current_user.id )
@users = @follows.collect { |f| f.to_id }
@users << current_user.id @chirps = Chirp.select{|c| @users.include?( c.user_id )} @chirps = @chirps.sort_by{ |c| c[:created_at] }.reverse Choose own follows in the 1st line, then make ids list in the 2nd line, add self in the 3rd line, extract followed chirps in the 4th line, and sort in reverse order if tweeted time in the 5th line. Index action of Chirps controller views/chirps/index.html.erb So that ‘faces’ are always displayed, modify the face display part as the following; Now it looks like twitter, a bit… How far we should go, to get similar with the real one… We have a lot of things to do for “real twitter” site. Display the “elapsed time” since the tweet is uploaded, instead of “tweeted_at” timestamp. (Also, time should be formatted) Display self-introduction. How to cope with the tweets after the user’s withdrawal, and such. Whatever you want to do, do them by yourself as your study challenge.