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

ローカルサーバーが起動しなくてやった事

1:エラーをぐぐる

2:ひたすらぐぐる

qiita.com

 これで解決しました。

ターミナルを切らずにブラウザを閉じてしまってエラーが起きた模様。

 

ターミナルが動かない

$ spring stop が原因らしい

治った。

【未経験プログラミング】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 を取得することができます。

 

 

 

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

TOPページ作成

 

ユーザー登録機能作成

Model データベースで永久保存する必要がある。

   必要なのはユーザー名、メールアドレス、ログイン認証の為のユーザーパス(暗号化される)

それぞれ name mail password_digest

暗号化された文字をダイジェストと言う。

モデルとマイグレーションファイルを作成。

rails g model User name:string email:string password_digest:string

db/migrateファイル確認。3箇所カラム問題なしであればマイグレーション

rails db:migrate

has_secure_passwordを記入でパスワードが有効

あまり深く考える必要はありません。password_digest カラムを用意し、モデルファイルに has_secure_password を記述すれば、ログイン認証のための準備を良しなにはからってくれると覚えておきましょう。

gemファイル

bcryptをインストール →パスワードダイジェストが有効になった。

 

各カラムのバリテーションを行う

name 

validates :name, presence: true, length: { maximum: 50 }

email
validates :email, presence: true, length: { maximum: 255 },
format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i },
uniqueness: { case_sensitive: false }

case_sensitive: false 大文字小文字 区別しない

before_save { self.email.downcase! } 保存後は小文字で保存されている。

7.2

Router

get 'signup', to: 'users#new'
resources :users, only: [:index, :show, :new, :create]

また、既に resources で users#new は設定されているのに、 get 'signup', to: 'users#new' をわざわざルーティングに追加したのは、ユーザの新規登録 URL を /signup にしたかったからです。 resources :users で生成される URL である /users/new は少し格好悪く思えます。そんなときには get 'signup' のように個別に設定することで解決します。また、 resources に :new も追加しているので /users/new でも新規登録ページが表示されます。それが嫌な場合には only 内の :new は削除します。

 

.7.3users#index

UsersContoroller作成:rails g controller users index show new create

 app/views/users/create.html.erb は不要の為削除

View フォロー/フォロワーの表示にusers/_users.html.erb使用するので先にパーシャルをしている。
<%= render 'users', users: @users %>

 

app/views/users/_users.html.erb

gravatar_urlは画像表示を変更するメソッド

定義されていない為Helper実装までここはエラーがでる。

 

rails g helper users →app/helpers/users_helper.rb

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

【未経験プログラミング】bootstrap【28日-29日】

viewport ありなしで表示の縮小しないようになる。<モバイル

<meta name="viewport" content="width=device-width, initial-scale=1">

グリッド

横幅いっぱいを12カラム

https://techacademy.s3.amazonaws.com/bootcamp/frontend/bootstrap/5-grid-system-col.png

 隙間をあける場合

"col-sm-offset-2 col-sm-5" 

メディアエクリ

特定の表示環境に対してだけCSSを適用させることができる。

表示幅500px未満では黒(#000)、表示幅500pxでは赤(#f00)

background-color: #000;

@media (min-width: 500px) {body {background-color:#f00;} }

フォーム <input type="text" class="form-control">

のようにinputに class="form-control"を追加すると青い枠が適用される。

 

 

【未経験プログラミング】Controlloer【27日】

cdapp/controllers/messages_controller.rにRESTfulなルーティングを書く。

def index ~end

def show ~end・・・・・・def destroy end

Controller 内でルーティングと同じ名前のメソッド名として定義すれば、対応させられます

 

Viewの構成

Viewは基本HTMLを記述する。

HTMLを書くと共通部分が出てくる。共通としてまとめないと毎回色々なファイルを修正する必要がでてくる。

app/views/layouts/application.html.erbに共通部分記載

yield … 各Actionに対するViewを生成します

例えば/messages とルーティングにブラウザでアクセスするとmessagecontrollerのindexアクションが呼び出され→app/views/layouts/application.html.erbが呼び出される

 

messages#indexに7つのルーティングを実装する。

Rails では ActiveRecord と呼ばれるライブラリを利用することで、SQL を一切書かずにレコードの CRUD 操作を行うことができます

モデルレコードはCRUD操作をする。

 

all 全てのレコードを取得する

new 新規レコードのためのモデルインスタンスを作成する

find idを指定して検索

find_by id以外でも指定して検索

where 検索条件を文字列、配列、ハッシュのいずれかの方法で与えることができる

first 最初のレコードを1件だけ取得する

save レコードの作成

update, save データの更新

destroy データの削除

 

indexをコーディング

indexアクションの役割はMessageモデルのレコード表示です。

一覧表示をするので Message.all    コーディング→    @messages = Message.all

@messagesはview側(index.html.erb)で使うことでControllerからViewへ変数を渡す事ができる。

  

 

 

 

 

【未経験プログラミング】ModelからRoutes【27日】

メッセージボード

・ HTTPメソッドは8つ:GET,POST,PUT,DELETE,HEAD,OPTIONS,TRANCE,CONNECT

そのうちCRUD:

CREATE:post(あらたらしいURLの作成)/put 子リソースの作成、データの追加、

READ:get リソースの取得

UPDATE:put リソースの更新、追加

DELETE:delete リソース削除

ローカルPCのファイルシステムで考えるとわかりやすく、
POSTは「新しいファイルを生成」。
PUTはファイルの置き換え(存在しなければそのまま配置される)。
PATCHはファイルを開いて中身を更新。
DELETEはファイルを削除。

・リソースとはWEB上で表示されるものすべて。

・WebアプリケーションはURLに対してHTTPリクエストメソッドを送りリソースを操作する。

Webアプリケーションフレイムワークとは Web開発における共通処理をまとめあげたものがWebアプリケーションフレイムワーク。

・ライブラリとフレイムワーク:

https://techacademy.s3.amazonaws.com/bootcamp/webapp/message-board/rails_rails.png

MVC

HTTPメソッド→Rails(Router→controller→model→DB→model→controller→view→Webブラウザ

 

  • Routerは、URLのルーティングを一元管理してる
  • Controllerは、HTTPリクエストの処理を担っている
  • Viewは、HTTPレスポンスとして返されるWebページ

上記3つはModelと違い関係性が高い

  1. Model(リソースであり操作対象である。)
  2. Router
  3. ルーティング毎に
    1.1. Controller
    1.2. View

Modelで使用するCRUDメソッド一覧 rails c

all(全レコードを取得)

new(新規レコードの為のモデルインスタンスを作成)

find(idを指定して検索)

find_by id以外でも指定して検索、

where 検索条件を文字列、配列、ハッシュのいずれかの方法で与えることができる、first 最初のレコードを1件だけ取得する、

saveレコードの作成

updateレコードのi更新 

dstroyデータ削除

コードでデータベースを操作できる事をORMという。ActiveRecordはORMをサポートしている。messe

 

https://techacademy.s3.amazonaws.com/bootcamp/webapp/message-board/rcv_rails.png

Routes.rb → messages_controller.rb →messagesフォルダ

 

ソースに対する CRUD のための4つのルーティング

Web アプリケーションは、ユーザが HTTP リクエストの4つの CRUD メソッド(POST, GET, PUT, DELETE)を使って、Web上のリソースを操作できるアプリケーションでした。

 

リソース1つのCRUDに対応するHTTPリクエストはGET POST PUT DELETEです。

get 'messages/:id', to: 'messages#show'
post 'messages', to: 'messages#create'
put 'messages/:id', to: 'messages#update'
delete 'messages/:id', to: 'messages#destroy'

:idはURLのmessages/1 の/1部分に対してのCRUDが実行できる。`POSTは新規URL作成の為書いてない。特定の何々にアクセスする(show)or更新する(put)or削除する(delete)

うえ4つは一覧ページ(index)がないため詳細ページにたどり着けない。

もちろんURL直接打てばいける。その為補助が必要

showには→:get 'messages', to: 'messages#index'    詳細ページの前のindex

createには→:get 'messages/new', to: 'messages#new  新規作成用のフォームpg

updateには→:get 'messages/:id/edit', to: 'messages#edit' データを渡す必要

上記7個をを省略

resources :messages   

#RESTful なルーティングと呼ばれる=CRUD操作に必要な7種類のアクションです。(index, show, new, create, edit, update, destroy)#

 

root to: 'messages#index'

rootメソッドを使用することで、Railsがルート'/'とすべき場所を指定できます。

そのため→root GET / messages#index が追加される。

 

 

【未経験プログラミング】Railsのタスクアプリを作成する。【24日~26日】

エラーメッセージを表示

バリデーション

 

フォームはnew、editにある。

validates :status, presence: true, length: { maximum: 10 }

 ページネーション:HPの2ページ目にいくやつ

gemをインストールする:gemfilを開き 最下段に gem 'いれたいgem名'

            ターミナルでbundle install

def index 

@tasks = Task.all          .page(params[:page]) ←追加TOPページに表示するって意味かと .per(25)がデフォルト 数字を変えられる。

<h1>タスク一覧</h1>

<ul>
<% @tasks.each do |task| %>
<li><%= link_to task.id, task %> : <%= task.status %>&gt; <%= task.content %></li>
<% end %>
</ul>
<%= paginate @tasks %> bodyの下段にnextやlastが表示される。