【未経験プログラミング】twitterクローン【34日】

Gravatar

https://ja.gravatar.com/

 ブログやコメントを投稿する際に名前の側に表示される画像です

 app/helpers/users_helper.rb

メソッドを定義する

module UsersHelper
def gravatar_url(user, options = {size: 80})
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
size = options[:size]
"https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
end
end

users#show

contorller

app/controllers/users_controller.rbにメソッドを作成

id を

def show
@user = User.find(params[:id])
end

 id が指定されているので、 User.find(params[:id]) によって1つだけ取得します。そのため、 @user 変数も単数形の命名にしています。GETメソッドやPOSTメソッドなどや、URL のパラメータやデータは全て params に代入されて受け取れます。

app/views/users/show.html.erb

  <!--両端揃えタブ・メニューの場合は、ul要素のclass属性にnav nav-tabs nav-justifiedを指定する。-->bootstrap3日本語リファレンスより↓

http://bootstrap3.cyberlab.info/components/navs.html

7.5app/views/users/new.html.erb

users#new

def new
@user = User.new
end

class="text-center"  textを真ん中に。

calss="row" 1列のカラム全部

class="form-group"

http://bootstrap3.cyberlab.info/css/forms.html

class="form-control" 幅がwidth: 100%;になる。

form部分はemail,password,nameの3箇所分作成

最後に投稿部分作成

<%= f.submit 'Sign up', class* 'btn btn-primary btn-block' %>
<% end %>

7users#create

Contoroller

redirect_to と render の違い

redirect_to @user は、 処理を users#show のアクションへと強制的に移動させるもので、create アクション実行後に更に show アクションが実行され、show.html.erb が呼ばれます。render :new は、単にmessages/new.html.erb を表示するだけです(messages#newのアクションは実行しない)。

createの部分はストロングパラメーターを使う必要がある。(セキュア)

params

params.require

params.require.permit

 

view

save成功時にはredirect_to_ @userに行き駄目ならrender :newに行く。

createに対応するviewはいらないが、エラーメッセージは実装する必要がある。

<%= render 'layoutes/error_messages', model: f.object %>

 

トップページにユーザーリンク登録

sign up now というボタンをつける。

app/views/toppages/index.html.erb

class center jumbotron  幅100%にする

class text-center 

class btn btn-lg btn-primary ボタン設置 ボタン大 ボタンの色プライマリー(青)

 

ログイン機能

HTTPはステートレス通信

ステート(状態)レス(無い)

ログイン情報はブラウザ内部とサーバ(rails)に保存される。

ブラウザがサーバにアクセスするたびに毎回HTTPで送受信している。

ブラウザがもっている情報はCookieとして保存

rails側はSessionとして保存している。 =Cookieとサーバーのsessionはお互いに称号している。

 

Router

config/routes.rb

railsが用意しているsessionシステムを使う。

get 'login', to: 'sessions#new'
post 'login', to: 'sessions#create'
delete 'logout', to: 'sessions#destroy'

 

rails g controller sessions new create destroy

[def new def create def destroy]

ログインフォームを作る。

対応するModelが無いのでコードの追加はなし

def new

end

app/views/sessions/new.html.erb

ログインの為アドレスとパスワードでログイン

ナビバーにログインリンクを追加する。

<li><%= link_to 'Login', login_path %><li>

 

sessions#create

sessions#create が実質的にログイン処理を担当するアクションになります。

session[:user_id]にログインユーザーのidが代入された時点でログイン完了となる。

controller

app/controllers/sessions_controller.rb

def create

form_for(:session, ... とした場合でも Model のインスタンスを指定したときと同様に、 params にフォームデータは代入されています

取り出すときはparams[:session][:email] のように二段階で指定して取得できます。

これを利用してemail = params[:session][:email].downcase 

フォームデータを小文字で受け取る、

次にlogin(email,password ログイン可能なメソッドが定義されている、

このメソッドはログイン成否でtrue、faleseを返す仕様。

userのpasswordがあっているか@user.authenticate(password)

で確認している。

if @user && @user.authenticate(password)

はemail,passwordの組み合わせが間違っていた場合にログインできないよう仕様になっている。

session[:user_id] = @user.id によってブラウザにはCookieとしてサーバーにはSessionとしてログイン状態が保持される。

 

view

ログイン後のトップページ

app/views/toppages/index.html.erb

login_in? current_userは仮のメソッド

ログイン後のナビバー

app/views/layouts/_navbar.html.erb

ここの書き方勉強する。

 

8.5

ログイン後のナビバー

class="collapse navbar-collapse" id="bs-example-navbar-collapse-1

 

class="dropdown' プルダウンみたいなやつ

<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><%= current_user.name %> <span class="caret"></span></a>

dropdown-toggleクラスを使いdata-toggle="dropdown"属性のボタンまたはリンクを使用する。

 

Helper

rails g helper sessions で作成

app/helpers/sessions_helper.rb

@current_user ||= User.find_by(id: session[:user_id])

!!current_user

||=という代入演算子を使っている。

if @current_user.nil?
@current_user = User.find_by(id: session[:user_id])
else
@current_user
end

と同じ意味になる。

current_userメソッド:サインインしているユーザーか取得する。

user_sessionメソッド:ユーザーのセッション情報にアクセスする

user_signed_in?メソッド:ユーザーがサインイン済かどうか判定する。

 

find(id)とfind_by(id)の違い

ユーザーが見つからなかった時のエラーが発生するか

/users/100000000 

nilだけを返すか、エラーページが表示されログインができなくなる。

 

ログアウトの実装

Controller

def destroy
session[:user_id] = nil
flash[:success] = 'ログアウトしました'
redirect_to_root_url
end

 

ログイン要求処理

indexshowはログインしていないユーザーに見せたくない、users#index, users#show のアクションには必ず事前にログイン認証を確認するような処理を追加します。

 

app/controllers/application_controller.rb

def require_user_logged_in
unless logged_in?
redirect_to_root_url
end

また、ここで Helper に定義していた logged_in? を使用していますが、実は Controller から Helper のメソッドを使うことはデフォルトではできません。そのため、ApplicationController に include SessionsHelper を追加します。

 

before_action :require_user_logged_in, only: [:index, :show]

before_actionではonly:で指定されたアクションに対して事前処理を設定できる。

今回は indexshow において、事前に require_user_logged_in が実行されるようになります

require_user_logged_in はログイン状態を確認し、ログインしていれば何もせず、ログインしていなければログインページへ強制的にリダイレクトさせます。

これで会員制のサービスを開発することができる。

 

投稿機能

Model

ユーザーの投稿をMicropost モデル名で作成していく。

UserとMicropostは一対多

rails g model Micropost content:string user:references

マイグレーション

rails db:migrate

 

Micropost Model

app/models/micropost.rb

class Micropost < ApplicationRecord
belongs_to :user
end

既に belongs_to :user が書かれています。これは、User と Micropost の一対多を表現しています。このコードのおかげで、micropost.user とすると、この micropost インスタンスを持っている User を取得することができます。