20200602のGitに関する記事は11件です。

GitHubの初回コミットは空でするべきかもしれない

なぜ?

さっき、初回のコミットで100MBを超えるファイルを入れてしまった。
勿論プッシュすることもできず、取り消す方法もよく分からなかった。(初回以外のコミットなら、指定のコミットまでリセットすることでキャンセルできる)
結局、PC上からローカルリポジトリごとすべて消去して、一からやり直すことで解決した。
これで3時間無駄にした。
もうこんなの御免だ。

空でコミットするって?

私の場合、「void_file.txt」という空テキストデータを作って、それだけを何よりも先に、一度コミットするという手法を取ることにした。
まだGit初心者なので、理に適ってないやり方かもしれない。
少なくともこれでプッシュする前なら、この空コミットまでリセットしてあげることでなんとかなるだろう。

なんか頭にきたことを走り書きしているので、駄文だとは思うが、以上である。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git pull出来ないときの対処法

個人開発を進めて行く中で、git pullできないことがありました。

$ git pull

試したこと

git stashコマンドを入力。
(変更しているファイルすべてを別の場所に保存しておいて一時的に変更していない状態に戻す)

$ git stash

このコマンドを実行すると無事git pullできました。


ちなみに

$ git stash list

上記のコマンドで、一時的に保存したリストを確認できます。

$ git stash list
stash@{0}: WIP on follow_unfollow: 1ef591e fix users controller

以下のコマンドで、退避していたスタッシュを元に戻せます。

$ git stash pop

終わり。

本番環境でpullしたらコンフリクト?解決法3パターン!【Please commit your changes or stash them before you merge】

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GITについて初歩的なところから勉強してみた

(1)はじめに

最近、業務でGitを使うことになり、勉強をはじめたばっかりの初心者です。
そもそも、PULL!?PUSH!?リポジトリ!?みたいな状態だったので、初歩的なことから勉強してみましたので備忘録として残していこうと思います。
(基礎的なことしか書いてないです)

(2)用語の説明

リポジトリについて

リポジトリとは、フォルダ、ファイル、ソースなどを保存しておく場所のことを指す。
Gitでは以下の2種類存在する。
・リモートリポジトリ:サーバー上に配置され、ここでチームで共有する。
・ローカルリポジトリ:ユーザーそれぞれのPC上に配置されている。

Aさんと同じソースを共有しているとすると、リポジトリは、こんな感じ。
スクリーンショット 2020-06-02 19.29.15.png

詳細には、リポジトリについてはこのようになっている。
masterブランチ(オレンジで囲ったところ)はデフォルトでできる。
・リモートリポジトリ:デフォルトで「origin」と言う名前がつけられる。
・リモート追跡ブランチ:「リモートブランチ」とも呼ばれる。リモートリポジトリを追跡するブランチ。リモートリポジトリのブランチ名を引き継ぐ。(リモートリポジトリが、「mybranch」だったら、リモート追跡ブランチは、「origin/mybranch」となる)
スクリーンショット 2020-06-02 22.47.41.png

ブランチについて

作業履歴を分岐して記録していくもので、他のブランチに影響されない。
この図では、masterブランチとmybranchが存在する。
スクリーンショット 2020-06-02 22.47.36.png

実際にどこで使うの?と思ったので、実際にgit使っている方に聞いてみたところ、「Develop(開発用)」ブランチを作成して本番環境と分けたりするらしい。
(あと、この記事には書いてないけどコンフリクトが起きた時とか)

ブランチ関連のGitコマンドは…
・ブランチの作成(mybranchを作成する)
 git branch mybranch
・ブランチに入る(mybranchに入る)
 git checkout mybranch

 (ブランチに)入るなのに、ホテルのチェックインみたいな感じで"checkin"じゃないんだとモヤモヤしてました。
 "checkout"は、英語で、「(図書館で本を)借りる」という意味もあるようで、それからきているみたい。

(3)リモート・ローカルリポジトリの作成方法

2パターン紹介する。

方法1 : リモートリポジトリを作成してクローンする(コピーみたいなイメージ)

①リモートリポジトリの作成

Git Hubでは、リポジトリ名とか指定するだけでできた。
スクリーンショット 2020-06-02 21.30.38.png

②初めてGit Hubを触る際は、SSHキーの設定が必要となる。

※SSHキーの設定は、ここを参考にしました。
https://qiita.com/shizuma/items/2b2f873a0034839e47ce

③ローカルリポジトリを作成したい場所に移動して、リモートリポジトリ(①)をクローン(コピー)する

cd [ファイル]
git clone git@github.com:[ユーザー名]/[リモートリポジトリ名].git

※赤枠のところに、git@github.com:[ユーザー名]/[リモートリポジトリ名].gitがあるので、コピーしてもOK
スクリーンショット 2020-06-02 23.41.24.png

方法2 : ローカルリポジトリを作成して、pushする。

①リモートリポジトリの作成

方法1の①と同じ

②初めてGit Hubを触る際は、SSHキーの設定が必要となる。

方法1の②と同じ

③ローカルリポジトリを作成したい場所に移動して、ローカルリポジトリの作成

cd [ファイル]
git init

④ローカルリポジトリ(③)をリモートリポジトリ(①)にPUSH

git add .
git commit -m "first commit"
git remote add origin git@github.com:[ユーザー名]/[リモートリポジトリ名].git
git push origin master

(4)pull

なんとなく分かってきたところで、pullを扱う。
リモートリポジトリからローカルリポジトリへ最新版を融合(マージ)させるイメージ。
スクリーンショット 2020-06-02 22.25.33.png

Gitコマンドはこれだけ。
git pull

今回は、masterブランチのみを考える。
内部では、fetch、mergeという処理をしている。
スクリーンショット 2020-06-02 22.46.02.png

(5)push

pushするときは、以下の流れで行う。
git add .
git status
git commit -m 'message'
git push origin [ブランチ名]

git status では、add(ステージングエリアに追加)はされたけど、commit(ローカルリポジトリに反映)されていないものを確認することができる。(ファイルが追加されたよ〜とか)

スクリーンショット 2020-06-02 22.43.57.png

ちなみに、masterブランチのみを考えると
git add .
git status
git commit -m 'message'
git push origin master

スクリーンショット 2020-06-02 22.45.28.png

(6)まとめ
なんとなく理解した気がするのですが、やっぱり難しい…
コンフリクトの解消法とか、まだ完全に理解しきれてないので、いつかまとめようと思います。
Gitに関しては、慣れるのみなんだろうなあと思っています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitの使い方

gitの使い方

まずはclone
ネットからローカルに落とす

git clone リポジトリ

ブランチ作成

git branch ブランチ名

ブランチ切り替え

git checkout ブランチ名

変更したふぁいるをadd

git add 変更したファイル

変更したふぁいるをcommit

git commit -m 変更したファイル

ローカルのものをリモートにあげる(ブランチがリモートに無いとき)

git push --set-upstream origin ブランチ名

この後プルリクを送る

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gitでよく使うコマンド一覧

メモ用です。

#対象フォルダにgitをセット
git init

#今あるブランチの確認
git branch

#hogeのブランチに移る
git checkout hoge

#ブランチのマージ
git merge マージ先 マージさせるブランチ

#ブランチの削除
git branch -d 削除したいブランチ名

#gitのレポジトリに変更したファイルを追加
git add ファイル名

#新規作成、削除、変更全てを反映
git add -A

#新しく作られたファイルは反映せず、前のバージョンにあった変更のみ
git add -u

#新規作成と変更のみ反映で削除は反映しない
git add .

#現在のリモートレポジトリを確認
git remote -v

#gitのログを確認
git log

#masterブランチに戻るコマンドです。
git checkout master

#加えられたすべての変更を元に戻す新しいコミットを生成し、それを現在のブランチに適用するコマンドです。
git revert

#リモートレポジトリのmasterブランチにpushする。
git push origin master
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails Tutorial 第6版 学習まとめ 第2章

概要

この記事は私の知識をより確実なものにするためにRailsチュートリアル解説記事を書くことで理解を深め
勉強の一環としています。稀にとんでもない内容や間違えた内容が書いてあるかもしれませんので
ご了承ください。
できればそれとなく教えてくれますと幸いです・・・

出典
Railsチュートリアル第6版

この章でやること

toy_appの作成を通してscaffoldの強力な機能を知る
RESTアーキテクチャとは何か大まかに把握する。

Toy_appの生成

①hello_appと同じようにRailsのバージョンを指定して生成する

$ cd ~/environment
$ rails _6.0.3_ new toy_app
$ cd toy_app/

②Gemfileも新しくなったのでToyアプリ用に書き換える

Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

gem 'rails',      '6.0.3'
gem 'puma',       '4.3.4'
gem 'sass-rails', '5.1.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.4.5', require: false

group :development, :test do
  gem 'sqlite3', '1.4.1'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'capybara',           '3.28.0'
  gem 'selenium-webdriver', '3.142.4'
  gem 'webdrivers',         '4.1.2'
end

group :production do
  gem 'pg', '1.1.4'
end

# Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

③そして以前と同じく
bundle installを実行、

You have requested:
  listen = 3.1.5

The bundle currently has listen locked at 3.2.1.
Try running `bundle update listen`

If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`

このようなエラーが出たらGemfile.lockで引っかかっているのでGemfile.lockを一度削除するか
bundle updateを実行してから
bundle installする。

④最後にhello_appと同じくGitのバージョン管理下に置く。

$ git init
$ git add -A
$ git commit -m "Initialize repository"

ローカルのリポジトリはできたので、リモートのリポジトリをToyアプリ用に新規作成して
プッシュする。(リモートリポジトリ作成は第1章と同じ方法でGithubのサイト上で行う)
リポジトリは依然と同じくプライベートで。

$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/toy_app.git
$ git push -u origin master

⑤とりあえずデプロイもしてみる。
今の状態だと中身がないのでとりあえずhello_appと同じように
hello,worldを出力するように追記しておく

application_controller.rb
class ApplicationController < ActionController::Base

  def hello
    render html: "hello, world!"
  end
end
routes.rb
Rails.application.routes.draw do
  root 'application#hello'
end

つづいてこの変更をコミット&Github/Herokuにプッシュ

$ git commit -am "Add hello"  
$ heroku create
$ git push && git push heroku master

Userモデルを作成する

ユーザーのモデル設計

ユーザーのデータモデル
Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#sec-modeling_demo_users

id,name,emailの属性がそれぞれテーブルのカラムに相当する。

マイクロポストのモデル設計

マイクロポストはTwitterのツイートと同じような140文字程度の短い投稿が前提となる。
投稿のid、投稿のテキスト内容を格納するtext型のcontent、誰の投稿かを記録するためのuser_idも追加すると

マイクロポストのデータモデル
Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#sec-modeling_demo_microposts

このようなデータモデルになる。

Usersリソース

さっそくUsersリソースからRailsをscaffoldジェネレータで生成する。

$ rails generate scaffold User name:string email:string

書き方はrails generate scaffold リソース名 カラム名:データ型 ~ となる。
id属性は必ず1つのモデルに1つ主キーとして付加されるので書く必要はない

scaffoldでUserモデルを作成したがこのままでは使えない。
ジェネレータで作成したデータベースはマイグレート(migrate)する必要がある。

データベースをマイグレートする↓

$ rails db:migrate

これでローカルWebサーバーを実行できるようになったので、Cloud9を使っている場合は
第1章と同じくdevelopment.rbを編集してCloud9への接続を許可しておく。

development.rb
Rails.application.configure do
  .
  .
  .
  config.hosts.clear
end

あとは別タブでターミナルを起動し、rails serverを実行。
これでローカルサーバーが立ち上がり、hello,world!が表示される。

ユーザーページを探検する

先ほどの一連の流れでUsersリソースをscaffoldで生成したことで自動でユーザー管理用のページが多数追加されている。
ページのURLと内容は以下の通り。

URL アクション 用途
/users index すべてのユーザーを一覧するページ
/users/1 show id=1のユーザーを表示するページ
/users/new new 新規ユーザーを作成するページ
/users/1/edit edit id=1のユーザーを編集するページ

Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#sec-a_user_tour

ユーザーページの探検はRailsチュートリアルを参照。

演習

  1. F12キーなどでブラウザのデベロッパーツールを起動し、該当の箇所を調べると、リロード時に内容が削除されている。
  2. emailを入力しないで登録しても登録できてしまう。これはまずいので3章から作るアプリではこのような問題の対策もしていく。
  3. 間違えたメールアドレスを入力されても登録できてしまう。2と同じでこれも対策することになる。
  4. Are you sure?と警告メッセージが表示されるようになっている。こういったユーザーの使いやすいように工夫された機能も実装していく。

MVCの挙動

/usersのindexページを開くと内部でどういった処理をしているのか、MVCで図解するとこのようになる。
image.png
Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#sec-mvc_in_action

ブラウザからのリクエスト→ルーターが該当するアクションに割り当て→必要なデータをUserモデルに問い合わせる
→データベースからモデルがデータを取り出す→モデルがデータをコントローラに渡す
→インスタンス変数に受け取ったデータを代入してビューに渡す→ビューはHTMLを生成し、コントローラに渡す
→コントローラがブラウザに受け取ったHTMLを返す
という流れ。

Toyアプリのとりあえずの形ができたのでルートURLをToyアプリのインデックスページに変更してみる。

routes.rb
Rails.application.routes.draw do
  resources :users
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  root "users#index"
end

今回も書き方は同じで "コントローラ名#アクション名"で記述する

ここでscaffoldで生成されたusers_controllerをのぞいてみる

users_controller.rb
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

  # GET /users
  # GET /users.json
  def index
    @users = User.all
  end

  # GET /users/1
  # GET /users/1.json
  def show
  end

  # GET /users/new
  def new
    @user = User.new
  end

  # GET /users/1/edit
  def edit
  end


このような記述がされている。
1行目のUsersController < ApplicationControllerという記述は
Rubyの文法で継承を意味する。ここでは
ApplicationControllerを継承したUserControllerクラスという意味になる。

以下の表はRESTに対応するアクションの一覧で、
URLが一部重複するものがあるがこれらはHTTPリクエストの種類が別なため別なルートとカウントされる。

HTTPリクエスト URL アクション 用途
GET /users index すべてのユーザーを一覧するページ
GET /users/1 show id=1のユーザーを表示するページ
GET /users/new new 新規ユーザーを作成するページ
POST /users create ユーザーを作成するアクション
GET /users/1/edit edit id=1のユーザーを編集するページ
PATCH /users/1 update id=1のユーザーを更新するアクション
DELETE /users/1 destroy id=1のユーザーを削除するアクション

Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#table-demo_RESTful_users

users_controllerのindexアクションをみてみると

  def index
    @users = User.all
  end

このような記述になっている。
これは@users変数にUserデータベースのすべてのデータを取り出して代入する処理を行っている。

Userモデル自体は何も記述がなく非常にシンプルだが
Userクラスが継承している"ActiveRecordクラス"がDB操作に関する非常に多くの機能を持っているため
今回の場合はUser.allでデータベースからUserのデータを取り出すことができた。

この@users変数はindexアクションに対応するindexビューで使われている。
該当の場所をみてみる。

index.html.erb


<% @users.each do |user| %>
      <tr>
        <td><%= user.name %></td>
        <td><%= user.email %></td>
        <td><%= link_to 'Show', user %></td>
        <td><%= link_to 'Edit', edit_user_path(user) %></td>
        <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
<% end %>

この記述の<% @users.each do |user| %>の部分だが
この段階で簡潔に説明すると、@users変数に入っているデータ(レコード)を一つずつ引っ張り出して
userに代入し、endで囲まれた部分をそのレコードの数分繰り返す処理。
ユーザーが3人(A、B、C)といたら
Aのデータをuserに入れてhtmlを生成
Bのデータをuserに入れてhtmlを生成
Cのデータをuserに入れてhtmlを生成
という繰り返し処理を行っている。
現時点では理解しなくてもOK

演習

1.
①ブラウザからリクエストがルーターに送られる
②ルーターがリクエストに対応するコントローラのeditアクションに割り当てる。
③editアクションが必要とするデータをモデルにリクエストする。
④モデルがリクエストされたデータをデータベースから読み出し、コントローラに返す
⑤editアクションが対応するビューedit.html.erbを呼ぶ(この時ビューには読み出したデータを渡す。)
⑥ビューがHTMLを生成し、コントローラに返す。
⑦コントローラがブラウザに渡されたHTMLを返す。

2.
users_controllerのprivateメソッドに記述されている。

users_controller.rb
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]






  private
    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def user_params
      params.require(:user).permit(:name, :email)
    end
end

before_actionという記述でeditアクションを実行する前にset_userメソッドを実行するよう指定されている。
ser_userアクションでは@user変数にUserデータベースのリクエストされたIDのテーブルを読み出すという文が書いてある。

3.edit.html.erb

Usersリソースの欠点について

前回の演習でも挙げたがユーザー名やメールアドレスがめちゃくちゃでも登録できてしまう。

またログイン機構がないので誰でもユーザーを削除したり編集したりできてしまう。権限もくそもない。

そしてアプリの動作を確認するテストがほぼない。上記の内容が正しいか。アプリの機能が正しく動作するかなどの
テストが全くかかれていない。→不都合があっても見つからない

UIがダサい、レイアウトもめちゃくちゃこんなレイアウトのWebアプリはだれも使わない(断言)

理解が難しい。これに尽きる
Railsチュートリアルを1週読破した自分でさえも完全にコードを理解するのは難しい。
コードは基本簡潔にわかりやすく書かないとNG 

マイクロポストを作成する

MicropostsもUsersと同様scaffoldで生成してみる。

$ rails g scaffold Micropost content:text user_id:integer
Running via Spring preloader in process 3794
      invoke  active_record
      create    db/migrate/20200601141608_create_microposts.rb
      create    app/models/micropost.rb
      invoke    test_unit
      create      test/models/micropost_test.rb
      create      test/fixtures/microposts.yml
      invoke  resource_route
       route    resources :microposts
      invoke  scaffold_controller
      create    app/controllers/microposts_controller.rb
      invoke    erb
      create      app/views/microposts
      create      app/views/microposts/index.html.erb
      create      app/views/microposts/edit.html.erb
      create      app/views/microposts/show.html.erb
      create      app/views/microposts/new.html.erb
      create      app/views/microposts/_form.html.erb
      invoke    test_unit
      create      test/controllers/microposts_controller_test.rb
      create      test/system/microposts_test.rb
      invoke    helper
      create      app/helpers/microposts_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/microposts/index.json.jbuilder
      create      app/views/microposts/show.json.jbuilder
      create      app/views/microposts/_micropost.json.jbuilder
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/microposts.scss
      invoke  scss
   identical    app/assets/stylesheets/scaffolds.scss

Usersの生成時と同じようにまずはデータベースをマイグレートして使えるようにする。

$ rails db:migrate
== 20200601141608 CreateMicroposts: migrating =================================
-- create_table(:microposts)
   -> 0.0041s
== 20200601141608 CreateMicroposts: migrated (0.0048s) ========================

MicropostsもUsersの時と変わらず、ルーターが更新され、resourcesでRESTアーキテクチャに対応した
各ルーティングが割り当てられる。

HTTPリクエスト URL アクション 用途
GET /microposts index すべてのマイクロポストを表示するページ
GET /microposts/1 show id=1のマイクロポストを表示するページ
GET /microposts/new new マイクロポストを新規作成するページ
POST /microposts create マイクロポストを新規作成するアクション
GET /microposts/1/edit edit id=1のマイクロポストを編集するページ
PATCH /microposts/1 update id=1のマイクロポストを更新するアクション
DELETE /microposts/1 destroy id1のマイクロポストを削除する

Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#code-demo_microposts_resource

scaffoldで生成されるコードはクラス名が自分でつけた名前に代わるだけで他は変わらない。
つまり同じ構造である。

MicropostsもUsersと同じように/micropostsでインデックスページにアクセスでき、New micropostで投稿ができる。

演習

  1. Usersの時と同じく、中身が消える。
  2. これもUsersの時と同じで、現状対策されていないため空のユーザーで空の投稿ができてしまう。
  3. 文字数を制限するコードが生成されていないため、投稿できてしまう。(これも欠点の一つ)
  4. indexページからdestroyリンクを踏むことで削除できる。これも確認メッセージが表示されてから削除される。
マイクロポストをマイクロなポストに

前回の演習の3番目の項目で文字数制限がないため、長い文章でも投稿できてしまいマイクロでない問題が発覚した。
この問題を修正していく。

データベースの内容に制限(バリデーション)を加えることでこの問題を修正する。
具体的なコードは下のとおり

micropost.rb
class Micropost < ApplicationRecord
  validates :content, length:{maximum: 140}

end

データベースを扱うモデルにバリデーションを書くことでcontentを140字に制限する。
このコードは
contentのlengthのmaximumを140に制限するという、非常に単純なコード。
投稿の文字数の最大を140文字とも言い換えられる。

バリデーションを追加することでRailsがエラーを吐くようになった。
実際にMicropostを140文字以上で投稿してみた画面がこちら。
image.png

超優秀。

演習

  1. 上の画面のようにエラーを吐くようになり、indexページに戻っても投稿は追加されない。(データベースに登録されない)
  2. error_explanationクラスの中にulリストでエラーの内容が格納されている。エラーが増えればliタグのコンテンツがエラーとして追加される。
ユーザーとマイクロポストの関連付け

TwitterやQiitaなどでもそうだが
”一人のユーザーは複数の投稿を持っている”
具体的な言い方に換えると
ユーザIDが1の投稿は複数存在しうる。
こういった1対多のデータの関係性をRailsは超簡単に実装できる。
そのコードがこちら

user.rb
class User < ApplicationRecord
  has_many :microposts
end
micropost.rb
class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length:{maximum: 140}
end

Userはmicropostを複数持っている。
micropostsは一つのユーザーに属する。
この関係性をこのコードで実装している。

このコードを書くことでMicropostsのuser_idカラムの値からユーザーを表示することができる。
実際にやってみよう。

まずはRailsの機能を使えるコンソールrails consoleを起動する。
rails console内ではデータベースのデータやコードを自由に試せるので非常に便利。
まずはrails console内でユーザーを作成し、そのユーザーのIDをもったMicropostも作成する。

user1 = User.first
   (0.4ms)  SELECT sqlite_version(*)
  User Load (0.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
 => #<User id: 1, name: "takemo", email: "take.webengineer@gmail.com", created_at: "2020-05-31 14:00:23", updated_at: "2020-05-31 14:00:23"> 
2.6.3 :002 > user1.microposts

user1にUserデータベースの一番最初に登録されているデータを代入
ローカルサーバーで以前ユーザーをお試しで作ったのでそのデータが代入されている。

ここで先ほどの関連付けが役立つシーンがこちら

> user1.microposts
  Micropost Load (0.1ms)  SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ?  [["user_id", 1], ["LIMIT", 11]]
 => #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 1, content: "taskemodsjfa jl", user_id: 1, created_at: "2020-06-01 14:24:23", updated_at: "2020-06-01 14:24:23">, #<Micropost id: 3, content: "Ruby(ルビー)は、まつもとゆきひろ(通称: Matz)により開発されたオブジェクト指向スクリプト...", user_id: 1, created_at: "2020-06-01 14:27:03", updated_at: "2020-06-01 14:27:03">, #<Micropost id: 5, content: "異なるデータモデル同士の関連付けは、Railsの強力な機能です。ここでは、1人のユーザーに対し複数の...", user_id: 1, created_at: "2020-06-01 14:41:51", updated_at: "2020-06-01 14:41:51">]> 
2.6.3 :003 > 

関連付けによってUserには複数のMicropostが結びついていることになったので、user1.micropostsとすると
user1に結びついたMicropostをすべて取り出すことができる。(ユーザーが何を投稿したか調べられる。)

逆方向の使い方を試してみる(投稿から誰が投降したのかを調べる。)

> micropost = user1.microposts.first
  Micropost Load (0.1ms)  SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."id" ASC LIMIT ?  [["user_id", 1], ["LIMIT", 1]]
 => #<Micropost id: 1, content: "taskemodsjfa jl", user_id: 1, created_at: "2020-06-01 14:24:23", updated_at: "2020-06-01 14:24:23"> 

micropost変数にuser1(user_id=1)の最初のmicropostを代入した。
つまりmicropostからuser_idが1のユーザーを取り出せればいい。

> micropost.user
 => #<User id: 1, name: "takemo", email: "take.webengineer@gmail.com", created_at: "2020-05-31 14:00:23", updated_at: "2020-05-31 14:00:23"> 
2.6.3 :004 > 

micropost.user とするだけでmicropostが属するユーザーを取り出すことができた。
1対多の関連性をhas_manyとbelongs_toを使って実装するだけでこのような便利な使い方ができる。

演習

  1. @userのmicropostsの中でfirstのmicropostのcontentを表示すればいいのでそのままほかの行からコピペして書き換えるとこうなる。
show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @user.name %>
</p>

<p>
  <strong>Email:</strong>
  <%= @user.email %>
</p>


<p> 
  <strong>Micropost_first</strong>
  <%= @user.microposts.first.content %>
</p>
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>

↓結果
image.png

2.コードを追加したら実際に空投稿してみると
バリデーションに引っかかってエラーを吐いた。
image.png

3.FILL_INにはバリデーションを適用したいカラムを指定する。(nameとemail)

user.rb
class User < ApplicationRecord
  has_many :microposts
  validates :name, presence: true
  validates :email, presence: true
end

バリデーションを追加したのでこちらも空登録するとエラーを吐くようになった。
image.png

Railsの継承について

ここは何となくの理解でもとりあえずOK
Railsのモデルは User < ApplicationRecordというRuby特有の文法で継承されている。
モデルの継承の構造は図の通り
image.png

Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#fig-demo_model_inheritance

UserやMicropostといったRailsのモデルはすべてApplicationRecordクラスを継承している。
そしてApplicationRecordはActiveRecord::Baseという基本クラスを継承している。
このActiveRecordがデータベースを扱う機能を提供している。
User.firstのfirstメソッドなどもこのActiveRecordを継承していることにより使える。

コントローラーも似たような構造でできている。
image.png
Railsチュートリアル第6版より
https://railstutorial.jp/chapters/toy_app?version=6.0#fig-demo_controller_inheritance

各コントローラーはApplicationControllerを継承しておりApplicationControllerは
ActionController::Baseという基本クラスを継承していることにより
様々なコントローラーで等しくコントローラーの基本機能を使うことができる。
またApplicationControllerを継承しているのでApplicationControllerで定義したルールは
継承先の各コントローラーで適用され、定義したメソッドなども同じように使用できる。

演習

1.1行目

application_controller.rb
class ApplicationController < ActionController::Base
  def hello
    render html:"hello,world!"
  end
end

2.モデルが格納されているmodelsフォルダのapplication_record.rbの1行目

application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end

最後に

この章で作ったToyアプリをHerokuにデプロイする

$ git add -A
$ git commit -m "Finish toy app"
$ git push
$ git push heroku 

このままだとHeroku上でエラーが発生して本番環境でサイトが表示されない。
heroku logsでHeroku上のエラーログを追ってみる。
するとこのような行がある。

2020-06-01T15:52:35.330114+00:00 app[web.1]: [3a72d85c-e21f-41d2-92ce-40c241660d8f]
 ActionView::Template::Error (PG::UndefinedTable: ERROR:  relation "users" does not exist

PGとはPostgreSQLのことである。
意味はPGでusersテーブルが存在しないと怒られている。
本番環境のデータベースと開発環境のデータベースは違うため
マイグレーションを本番環境でも行わなければならない。
つまりマイグレーションをしていないから怒られている。

heroku run rails db:migrateで本番環境のデータベースをマイグレートする。
これでしっかり動作するはず。

演習

1.ここで先ほどの演習2.3.3.1をやっていると本番環境のデータベースにはマイクロポストが一つも登録されておらず
エラーを吐いてしまうため、演習で追加したコード部は削除して、コミット、プッシュしなおしておく。
image.png
うまくいけばこのようにユーザーを作成できる。


2.本番環境でも同じくマイクロポストを作成できることが確認できた。

image.png

3.もちろんちゃんと動く
image.png

←前の章へ

次の章へ→

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitを使ったチーム開発のために【2020年6月現在】

初心者の初心者である僕が、Gitを使えるようになるためによく見た動画は以下の3つです。これらを見ながら、実際に手を動かすのがとっても効果的です!

まずは基本を抑えよう!

https://www.youtube.com/watch?v=i1L3A0SLDyg&t=22s

https://www.youtube.com/watch?v=cdz-cs_kYto

https://www.youtube.com/watch?v=JispFS6zeDw&t=900s

https://www.youtube.com/watch?v=EjSgD1xb6zw

まとめ

これらを実践すればGitの基本的なことは、わかりますよ。最近はYouTubeで駆け出しエンジニア用の有益な動画がたくさんあるので、助かりますね。

とりわけプログラミングは文字よりも、図や写真、動画がぴったりです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

githubのはじめ方

メアドとユーザー名

まずgithubに登録済みのメアドとユーザー名をコマンドを用いて登録します。

ユーザー名とメールアドレスを設定する
Git上で使いたい情報を入力します。下記のコマンドで【ユーザー名】と【メールアドレス】の部分を、自分の情報に置き換えてください。

$ git config --global user.name "【ユーザー名】"
$ git config --global user.email 【メールアドレス】
以下のコマンドで設定を確認できます。

$ git config --list
user.name=【ユーザー名】
user.email=【メールアドレス】
...

【参考】
https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000

SSHキーを設定

鍵を設定します。

1:鍵を作成する。
2:作成した鍵をコピーする。
3:gitghubに公開鍵を登録する。
4:configファイルを作成し直す。(接続確認)

【参考】
http://tusukuru.hatenablog.com/entry/2018/08/29/021651

ラスト

以下のコマンドを実行。

git init
git add README.md
git commit -m "first commit"
git remote add origin URL
git push -u origin master
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初学者によるGitの使い方メモ2

はじめに

この記事は、初学者によるGitの使い方メモ1 の続きです。

Gitコマンド

変更内容を把握

git  addする前の変更分
$ git diff
$ git diff <ファイル名>

differenceの略
特定のファイルが見たい場合はファイル名を付ける。

git  addした後の変更分
$ git diff --staged

git addした後、つまりステージに上げた、ステージングした状態で確認すること。

変更履歴の確認

コミットログの表示
$ git log
$ git log --online #一行で表示
$ git log -p <ファイル名> #ファイルの変更差分の確認

ブランチの作成

ブランチの新規追加
$ git branch <ブランチ名>

複数機能を並行して開発するのがブランチである。
最後に大元の機能に取り込む。
ブランチをきれば、他の人の変更を受けない。

ブランチの切替

ブランチの切替
$ git checkout <既存ブランチ名>
$ git checkout -b <新ブランチ名> #ブランチを新規作成 + 切替

ブランチを切り替える。
コミットしたらmasterブランチとは別れる。
HEADとは、現在作業している場所を示してるポインタである。

変更をマージ

変更を取り込む
$ git merge <ブランチ名>
$ git merge <リモート名/ブランチ名> #github上の内容を取り込む

(例)作業場所がブランチの場合
$ git merge origin/master
origin/masterの場合、github上の内容を作業中のブランチに取り込む

Fast Foward:早送りマージ

ポインタを前に進めるだけのマージ
枝分かれせずにmasterがbranchにポインタを変えること。

Auto Merge

masterとbranchがそれぞれ別の開発をし、
枝分かれしているとき、masterをベースに
branchの内容を取り込み、新たなコミットを作ること。

コンフリクトを起こした場合
どのファイルがコンフリクト起こしたか確認
$ git status
コンフリクトを起こしたファイル
<h1>あなたの好きな食べ物は?</h1>
<<<<<<<HEAD
<p>寿司</p>
<p>うどん</p>
=======
<p>ハンバーグ</p>
>>>>>>>branch

HEADは現在の作業場所
HEADの変更分
branchの変更分が重なっている。
<< == >> を削除しファイルを書き換える

解決したファイル
<h1>あなたの好きな食べ物は?</h1>
<p>寿司</p>
<p>ハンバーグ</p>

最後にaddしてcommitすれば解決する。
コンフリクトを起こさないように、複数人で同じファイルを変更しない。
又、pullするときは同じブランチ名からpullすること。

ブランチ名の変更

名前の変更
$ git branch -m <ブランチ名>

ブランチの削除

ブランチの削除
$ git branch -d <ブランチ名>

masterにまだマージされていない変更分がある場合
そのブランチは削除されない。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git pull で、ローカルを強制上書き

git fetch origin master
git reset --hard origin/master

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git remote 名前変更

追加

$ git remote add new https://github.com/xxxx/xxx.git

登録確認

$ git remote -v
new https://github.com/xxxx/xxx.git (fetch)
new https://github.com/xxxx/xxx.git (push)

名前変更

$ git remote rename new upstream

$ git remote -v
upstream    https://github.com/xxxx/xxx.git (fetch)
upstream    https://github.com/xxxx/xxx.git (push)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む