【未経験プログラミング】twitterクローン【34日】
Gravatar
ブログやコメントを投稿する際に名前の側に表示される画像です
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:で指定されたアクションに対して事前処理を設定できる。
今回は index
, show
において、事前に 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 を取得することができます。