20200626のRailsに関する記事は16件です。

Ruby on Rails チュートリアル(第4版) 第2章

$ heroku createでbash: heroku: command not foundと出たので1章を見ながらherokuをインストール。

2.2.1 演習

1.CSSを知っている読者へ: 新しいユーザーを作成し、ブラウザのHTMLインスペクター機能を使って「User was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?
 <p id="notice">User was successfully created.</p>
 リロードすると消える。<p id="notice"></p>

2.emailを入力せず、名前だけを入力しようとした場合、どうなるでしょうか?
 emailの入力なしでもユーザー登録が出来る。

3.「@example.com」のような間違ったメールアドレスを入力して更新しようとした場合、どうなるでしょうか?
 間違ったメールアドレスを入力しても更新出来る。

4.上記の演習で作成したユーザーを削除してみてください。ユーザーを削除したとき、Railsはどんなメッセージを表示するでしょうか?
 User was successfully destroyed.

2.2.2 演習

1.図 2.11を参考にしながら、/users/1/edit というURLにアクセスしたときの振る舞いについて図を書いてみてください。
rails.png

2.図示した振る舞いを見ながら、Scaffoldで生成されたコードの中でデータベースからユーザー情報を取得しているコードを探してみてください。

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

3.ユーザーの情報を編集するページのファイル名は何でしょうか?
 app/views/users/edit.html.erb

2.3.1 演習

1.CSSを知っている読者へ: 新しいマイクロポストを作成し、ブラウザのHTMLインスペクター機能を使って「Micropost was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?
 <p id="notice">Micropost was successfully created.</p>
 リロードすると消える。<p id="notice"></p>

2.マイクロポストの作成画面で、ContentもUserも空にして作成しようとするどうなるでしょうか?
 Content、Userが空でも作成できる。

3.141文字以上の文字列をContentに入力した状態で、マイクロポストを作成しようとするとどうなるでしょうか? (ヒント: WikipediaのRubyの記事にある1段落目がちょうど150文字程度ですが、どうなりますか?)
141文字以上でも作成できる。

4.上記の演習で作成したマイクロポストを削除してみましょう。
 削除するだけ

2.3.2 演習

1.先ほど2.3.1.1の演習でやったように、もう一度Contentに141文字以上を入力してみましょう。どのように振る舞いが変わったでしょうか?
 エラーが出るようになった

1 error prohibited this micropost from being saved:
Content is too long (maximum is 140 characters)

2.CSSを知っている読者へ: ブラウザのHTMLインスペクター機能を使って、表示されたエラーメッセージを調べてみてください。

<div id="error_explanation">
 <h2>1 error prohibited this micropost from being saved:</h2>
 <ul>
   <li>Content is too long (maximum is 140 characters)</li>
 </ul>
</div>

2.3.3 演習

1.ユーザーのshowページを編集し、ユーザーの最初のマイクロポストを表示してみましょう。同ファイル内の他のコードから文法を推測してみてください (コラム 1.1で紹介した技術の出番です)。うまく表示できたかどうか、/users/1 にアクセスして確認してみましょう。

app/views/users/show.html.erb
<p>
  <strong>Micropost:</strong>
  <%= @user.microposts.first.content %>
</p>

2.リスト 2.16は、マイクロポストのContentが存在しているかどうかを検証するバリデーションです。マイクロポストが空でないことを検証できているかどうか、実際に試してみましょう (図 2.16のようになっていると成功です)。
 エラーが出るようになった

1 error prohibited this micropost from being saved:
Content can't be blank

3.リスト 2.17のFILL_INとなっている箇所を書き換えて、Userモデルのnameとemailが存在していることを検証してみてください (図 2.17)。

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

2.3.4 演習

1.Applicationコントローラのファイルを開き、ApplicationControllerがActionController::Baseを継承している部分のコードを探してみてください。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

2.ApplicationRecordがActiveRecord::Baseを継承しているコードはどこにあるでしょうか? 先ほどの演習を参考に、探してみてください。ヒント: コントローラと本質的には同じ仕組みなので、app/modelsディレクトリ内にあるファイルを調べてみると...?)

app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base

2.3.5 演習

省略

メモ

validatesとかの設定はapp/modelsで行う。
本番環境のデータベースのマイグレーションが必要。

$ heroku run rails db:migrate

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

curlコマンドにより作成したapiでデータを取得する

環境

cloud9(api取得側)
local(api提供側)
ruby 2.6.3
Rails 6.0.2.1

結論

controller

def index
  uri = `curl -v -X GET "http://stage-smartyoyaku-env.ap-northeast- 1.elasticbeanstalk.com/api/v1/tasks" \
        -H "Authorization: Bearer ここにTokenを書く"`
  @test = JSON.parse(uri)
end

*取得できているかブラウザで確認します

viewfile

<%= @test %>

それまでのエラー内容

cloud9のターミナルでcurlコマンドを入力すると。。

curl: (7) Failed to connect to localhost port 3000: Connection refused

調べて見るとサーバーが立ち上がってない場合かポート番号が間違っているかのようです。
ブラウザでlocalhost:3000にアクセスしましたが問題なし。port番号もあっていましたが、、

もう一度整理

・cloud9側のアプリでcurlコマンドを叩いている。(取得する側)
・local環境の3000portでapiを提供しているアプリを立ち上げている。(提供する側)←ここ重要

ん?cloud9(インターネット上)からlocalには接続できないんじゃ、、

$ lsof -i:3000
$

cloud9上で3000portが使われているか確認→表示されない

つまりapiを提供する側はherokuなどでネットにurlを公開し、そこからデータを取ってくる必要があります。

注意点

ターミナルでcurlコマンドを打つ場合とcontrollerに書く場合は微妙に書き方が違う。
controllerではcurlコマンドを``で囲む。

ターミナルの場合

$ curl -v -X GET "http://stage-smartyoyaku-env.ap-northeast-1.elasticbeanstalk.com/api/v1/tasks" \
          -H "Authorization: Bearer ここにTokenを書く"
controllerの場合

def index
  uri = `curl -v -X GET "http://stage-smartyoyaku-env.ap-northeast- 1.elasticbeanstalk.com/api/v1/tasks" \
        -H "Authorization: Bearer ここにTokenを書く"`
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails gem rooを使って、エクセルファイルからデータ登録

目的

ユーザーが複数のデータをアプリに投稿したいとき、エクセルファイルを選択するとデータベースに保存できるようにしたい。

実装

アプリ立ち上げ

rails new sample_app -d postgresql
rails db:create

rails newで新規アプリを作成、データベースも作成する。

コントローラー作成

rails g controller users index

indexアクションを持つUserコントローラーを作成。
ルーターとビューも一緒に作成される。

モデル作成

rails g model user name:string email:string
rails db:migrate

usersテーブルには、string型のnameとemailのカラムを作成。

ビュー

app/views/users/index.html.erb
<h1>ユーザー一覧</h1>

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>名前</th>
      <th>Eメール</th>
    </tr>
  </thead>
  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td><%= user.id %></td>
        <td><%= user.name %></td>
        <td><%= user.email %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<%= form_with url: import_users_path, local: true do |form| %>
  <%= form.file_field :file %>
  <%= form.submit %>
<% end %>

投稿フォーム生成。ファイル自体を保存するわけではなく、params[:file]を送ったアクション:importにてUserを登録できるようにする。

ルーター

config/routes.rb
Rails.application.routes.draw do
  resources :users do
    collection do
      post :import
    end
  end
end

UserにPostメソッドの:importアクション用のルーティングを追加する。

コントローラー

app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def import
    User.import(params[:file])
    redirect_to users_url
  end
end

indexアクションはscaffoldを使ったときと同じで全レコードを取得し、@usersに代入。
importアクションは、params[:file]を受け取って、usersテーブルのレコードを作成するimportメソッドを使う。モデルには、importメソッドの定義を書く。

モデル

app/models/user.rb
class User < ApplicationRecord
  def self.import(file)
    xlsx = Roo::Excelx.new(file.tempfile)
    xlsx.each_row_streaming(offset: 1) do |row|
      user = self.new(id: row[0].value, name: row[1].value, email: row[2].value)
      next if self.pluck(:id).include?(user.id)
      user.save
    end
  end
end

Userモデルのモデルメソッドなので、def self.import の形で定義。params[:file].tempfileに送信したファイルのパスが入る。Roo::Excelx.new(file.tempfile)でファイルを読み取り、変数xlsxに代入。each_row_streamingメソッドで読み込んだファイルの行毎に処理を実行。
offsetオプションによって、処理を飛ばす行数を指定できる(一行目の項目欄を飛ばす)。
next if self.pluck(:id).include?(user.id)で同じidがusersテーブルに存在している場合は処理をスキップしている。

gem rooを使えるように準備をする。

gem rooを使う準備

Gemfile
gem "roo" #追記

ターミナルでbundle installする。また、config/application.rbにrequire "roo"を追記

config/application.rb
# 省略
require 'rails/all'
require "roo"
# 省略

これで、OK。

確認

サーバーを立ち上げ "http://localhost:3000/users" にアクセスして画面を確認する。

test.png
ファイルを選択を押して、次のようなエクセルファイルからデータを登録できる。
エクセル.PNG
登録後、次のように画面が変わっていることを確認する。
test.png

参考記事

https://qiita.com/seitarooodayo/items/c9d6955a12ca0b1fd1d4
https://qiita.com/guri3/items/f20487516311b2a3db37
本当に参考になりました!ありがとうございます!

後書き

応用して、社員表を一気に登録する機能をアプリに作ってみようと思います。

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

Rails gem rooを使って、エクセルファイルからデータ保存

目的

ユーザーが複数のデータをアプリに投稿したいとき、エクセルファイルを選択するとデータベースに保存できるようにしたい。

実装

アプリ立ち上げ

rails new sample_app -d postgresql
rails db:create

rails newで新規アプリを作成、データベースも作成する。

コントローラー作成

rails g controller users index

indexアクションを持つUserコントローラーを作成。
ルーターとビューも一緒に作成される。

モデル作成

rails g model user name:string email:string
rails db:migrate

usersテーブルには、string型のnameとemailのカラムを作成。

ビュー

app/views/users/index.html.erb
<h1>ユーザー一覧</h1>

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>名前</th>
      <th>Eメール</th>
    </tr>
  </thead>
  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td><%= user.id %></td>
        <td><%= user.name %></td>
        <td><%= user.email %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<%= form_with url: import_users_path, local: true do |form| %>
  <%= form.file_field :file %>
  <%= form.submit %>
<% end %>

投稿フォーム生成。ファイル自体を保存するわけではなく、params[:file]を送ったアクション:importにてUserを登録できるようにする。

ルーター

config/routes.rb
Rails.application.routes.draw do
  resources :users do
    collection do
      post :import
    end
  end
end

UserにPostメソッドの:importアクション用のルーティングを追加する。

コントローラー

app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def import
    User.import(params[:file])
    redirect_to users_url
  end
end

indexアクションはscaffoldを使ったときと同じで全レコードを取得し、@usersに代入。
importアクションは、params[:file]を受け取って、usersテーブルのレコードを作成するimportメソッドを使う。モデルには、importメソッドの定義を書く。

モデル

app/models/user.rb
class User < ApplicationRecord
  def self.import(file)
    xlsx = Roo::Excelx.new(file.tempfile)
    xlsx.each_row_streaming(offset: 1) do |row|
      user = self.new(id: row[0].value, name: row[1].value, email: row[2].value)
      next if self.pluck(:id).include?(user.id)
      user.save
    end
  end
end

Userモデルのモデルメソッドなので、def self.import の形で定義。params[:file].tempfileに送信したファイルのパスが入る。Roo::Excelx.new(file.tempfile)でファイルを読み取り、変数xlsxに代入。each_row_streamingメソッドで読み込んだファイルの行毎に処理を実行。
offsetオプションによって、処理を飛ばす行数を指定できる(一行目の項目欄を飛ばす)。
next if self.pluck(:id).include?(user.id)で同じidがusersテーブルに存在している場合は処理をスキップしている。

gem rooを使えるように準備をする。

gem rooを使う準備

Gemfile
gem "roo" #追記

ターミナルでbundle installする。また、config/application.rbにrequire "roo"を追記

config/application.rb
# 省略
require 'rails/all'
require "roo"
# 省略

これで、OK。

確認

サーバーを立ち上げ "http://localhost:3000/users" にアクセスして画面を確認する。

test.png
ファイルを選択を押して、次のようなエクセルファイルからデータを登録できる。
エクセル.PNG
登録後、次のように画面が変わっていることを確認する。
test.png

参考記事

https://qiita.com/seitarooodayo/items/c9d6955a12ca0b1fd1d4
https://qiita.com/guri3/items/f20487516311b2a3db37
本当に参考になりました!ありがとうございます!

後書き

応用して、社員表を一気に登録する機能をアプリに作ってみようと思います。

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

Ruby on Rails5 速習実践ガイド5.2対応 Chapter2

Chaptrt2 Railsアプリケーションをのぞいてみよう

Windows10の環境構築
実習でHyperVマネージャーにより、仮想環境はすでにあり。
Ubuntu 18.04.3をインストール
rbenv 1.1.2-30-gc879cb0 Gitを使ってGitHubからをインストール。
Ruby 2.5.1 インストール
Rails インストール
Node.js のインストール

JavaScriptを用いる場合、効率よく配信するためにJavaScriptを圧縮する機能が備わっているが、そのためにJavaScriptランタイムが必要となるためにインストール。

PostgreSQL をインストールしセットアップ
PostgreSQLを起動。
 sudo service postgresql start

 
 sudo su postgres -c 'createuser -s {Ubuntuのログインユーザ}'
 を打つと、以下のエラーが出た。

 psql: FATAL: role “postgres” does not exist
 {}無しでUbuntuのログインユーザー名を記載したらすんなり通りました。

scaffoldを使ってscaffold_appという名前で「ユーザー管理アプリケーション」をRailsのコマンドで自動生成させる。
 rails new scaffold_app -d postgresql

 rails new コマンドはRailsアプリケーションのひな型を生成。
アプリケーションの名前をscaffold_appと指定。
scaffold_appディレクトリと関連ファイルが生成されて、ログ出力される。
この後 bundle installが自動的に実行されて、Railsの実行に必要なgemがインストールされる。
データベースの作成。config/databese.ymlというファイルの定義をもとに。

bin/rails s db:create

「rails」ではなく「bin/rails」で、アプリケーションのルートディレクトリ直下のbinディレクトリにあるrailsというスクリプトを呼び出している。Gemfileどおりのgemを利用できる環境上でrailsコマンドを実行できる。
railsサーバー起動
 bin/rails s

railsは標準のHTTPサーバとしてPumaを採用。

WEBブラウザでサーバーの起動を確認
 アドレスバーにhttp://localhost:3000/を入力。

ユーザー管理機能のひな型を作る
「ユーザー」に関するscaffoldを自動生成。
 bin/rails generate scaffold user name:string address:string age:integer

ユーザー管理機能に使うテーブルをデータベースに作成。
 bin/rails db:migrate

ユーザー一覧画面を表示
 http://localhost:3000/users
WEBブラウザへ上のURLを入力してアクセス。

重要だと思ったポイント

  • ユーザーを管理するために必要な機能「CRUD」が生成されている。  「作成(create)」「読み出し(read)」「更新(update)」「削除(delete)」
  • コードの通り道 Railsアプリケーションは、MVC(モデル・ビュー・コントローラ)という考え方で構成。 コントローラーが呼ばれる。コントローラーにはリクエストに対する処理が書かれている「アクション」と呼ばれるメソッドが定義(一覧画面にアクセスした際はidnexアクション)されている。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails5 速習実践ガイド5.2対応 Chapter3

Capter3タスク管理アプリケーションを作ろう

CRUDを備えたシンプルな「タスク管理アプリケーション」を、scaffoldを使わずにゼロから作成。

環境

  • Ruby 2.5.1

  • Ruby on Rails 5.2.1

  • PostgreSQL 10.5

Railsのエラーメッセージなどを日本語で出せるようにする
GithubのRails-i18nリポジトリにある翻訳されたファイル(rawファイル)をconfig/locales/ja.ymlとしてダウンロード。

wget https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml --output-file=config/locales/ja.yml

config/locales/ja.ymlを確認すると、以下のログが記載されている。

--2020-06-26 14:40:30-- https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml
192.168.24.1:8080 に接続しています... 接続しました。
Proxy による接続要求を送信しました、応答を待っています... 200 OK
長さ: 5117 (5.0K) [text/plain]
`ja.yml' に保存中

0K ....                                                  100% 10.3M=0s

2020-06-26 14:40:31 (10.3 MB/s) - `ja.yml' へ保存完了 [5117/5117]

解決策としてWEBブラウザへ
https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml
を張り付ける。
表示された以下のテキストの内容をja.yml内に張り付けて保存。


ja:
activerecord:
errors:
messages:
record_invalid: 'バリデーションに失敗しました: %{errors}'
restrict_dependent_destroy:
has_one: "%{record}が存在しているので削除できません"
has_many: "%{record}が存在しているので削除できません"
date:
abbr_day_names:
- 日
- 月
- 火
- 水
- 木
- 金
- 土
abbr_month_names:
-
- 1月
- 2月
- 3月
- 4月
- 5月
- 6月
- 7月
- 8月
- 9月
- 10月
- 11月
- 12月
day_names:
- 日曜日
- 月曜日
- 火曜日
- 水曜日
- 木曜日
- 金曜日
- 土曜日
formats:
default: "%Y/%m/%d"
long: "%Y年%m月%d日(%a)"
short: "%m/%d"
month_names:
-
- 1月
- 2月
- 3月
- 4月
- 5月
- 6月
- 7月
- 8月
- 9月
- 10月
- 11月
- 12月
order:
- :year
- :month
- :day
datetime:
distance_in_words:
about_x_hours:
one: 約1時間
other: 約%{count}時間
about_x_months:
one: 約1ヶ月
other: 約%{count}ヶ月
about_x_years:
one: 約1年
other: 約%{count}年
almost_x_years:
one: 1年弱
other: "%{count}年弱"
half_a_minute: 30秒前後
less_than_x_seconds:
one: 1秒以内
other: "%{count}秒未満"
less_than_x_minutes:
one: 1分以内
other: "%{count}分未満"
over_x_years:
one: 1年以上
other: "%{count}年以上"
x_seconds:
one: 1秒
other: "%{count}秒"
x_minutes:
one: 1分
other: "%{count}分"
x_days:
one: 1日
other: "%{count}日"
x_months:
one: 1ヶ月
other: "%{count}ヶ月"
x_years:
one: 1年
other: "%{count}年"
prompts:
second: 秒
minute: 分
hour: 時
day: 日
month: 月
year: 年
errors:
format: "%{attribute}%{message}"
messages:
accepted: を受諾してください
blank: を入力してください
confirmation: と%{attribute}の入力が一致しません
empty: を入力してください
equal_to: は%{count}にしてください
even: は偶数にしてください
exclusion: は予約されています
greater_than: は%{count}より大きい値にしてください
greater_than_or_equal_to: は%{count}以上の値にしてください
inclusion: は一覧にありません
invalid: は不正な値です
less_than: は%{count}より小さい値にしてください
less_than_or_equal_to: は%{count}以下の値にしてください
model_invalid: 'バリデーションに失敗しました: %{errors}'
not_a_number: は数値で入力してください
not_an_integer: は整数で入力してください
odd: は奇数にしてください
other_than: は%{count}以外の値にしてください
present: は入力しないでください
required: を入力してください
taken: はすでに存在します
too_long: は%{count}文字以内で入力してください
too_short: は%{count}文字以上で入力してください
wrong_length: は%{count}文字で入力してください
template:
body: 次の項目を確認してください
header:
one: "%{model}にエラーが発生しました"
other: "%{model}に%{count}個のエラーが発生しました"
helpers:
select:
prompt: 選択してください
submit:
create: 登録する
submit: 保存する
update: 更新する
number:
currency:
format:
delimiter: ","
format: "%n%u"
precision: 0
separator: "."
significant: false
strip_insignificant_zeros: false
unit: 円
format:
delimiter: ","
precision: 3
separator: "."
significant: false
strip_insignificant_zeros: false
human:
decimal_units:
format: "%n %u"
units:
billion: 十億
million: 百万
quadrillion: 千兆
thousand: 千
trillion: 兆
unit: ''
format:
delimiter: ''
precision: 3
significant: true
strip_insignificant_zeros: true
storage_units:
format: "%n%u"
units:
byte: バイト
eb: EB
gb: GB
kb: KB
mb: MB
pb: PB
tb: TB
percentage:
format:
delimiter: ''
format: "%n%"
precision:
format:
delimiter: ''
support:
array:
last_word_connector: "、"
two_words_connector: "、"
words_connector: "、"
time:
am: 午前
formats:
default: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
long: "%Y/%m/%d %H:%M"
short: "%m/%d %H:%M"
pm: 午後

これでアプリケーション作成の下準備が整った。

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

[Rails] 画像ファイルを受け取って保存する

Progate学習メモ

view.rb
<input name="image" type="file">
controller.rb
image = params[:image]
# File.binwrite("path_to_画像ファイルを保存するフォルダ/画像ファイル名", 画像データ.read)
File.binwrite("public/user_images/#{@user.image_name}", image.read)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails チュートリアル(第4版) 第1章

11章で断念(バグ直そうとアレコレしてたら余計にどうにもならなくなってしまった…)してしまった為、
最初から理解を深めながらやってみようということで、
2周目のRailsチュートリアルを演習やバグや気になった点をメモしながら進めてみようと思います!

1.1.1 演習

1.Ruby on Railsで使うRuby gemはどのWebサイトにありますか?ヒント: 分からないときはとにかくググりましょう。
 ググってみた。 https://rubygems.org

2.現時点でのRailsの最新バージョンはいくつですか?
 ググってみry Ruby on Rails 6.0.3(リリース日:2020/05/06)

3.Ruby on Railsはこれまでに何回ダウンロードされたでしょうか?調べてみてください。
 ググっry 230,607,561回

1.3.2 演習

1.デフォルトのRailsページに表示されているものと比べて、今の自分のコンピュータにあるRubyのバージョンはいくつになっていますか?コマンドラインでruby -vを実行することで簡単に確認できます。
 ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]

2.同様にして、Railsのバージョンも調べてみましょう。調べたバージョンはリスト 1.1でインストールしたバージョンと一致しているでしょうか?
 rails -vを実行 Rails 5.1.6

1.3.4 演習

1.リスト 1.7のhelloアクションを書き換え、「hello, world!」の代わりに「hola, mundo!」と表示されるようにしてみましょう。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def hello
    render html: "hola, mundo!"
  end
end

2.Railsでは「非ASCII文字」もサポートされています。「¡Hola, mundo!」にはスペイン語特有の逆さ感嘆符「¡」が含まれています (図 1.16)18 。「¡」文字をMacで表示するには、Optionキーを押しながら1キーを押します。この文字をコピーして自分のエディタに貼り付ける方が早いかもしれません。
 1.のhola,mundo!¡Hola, mundo!に変更

3.リスト 1.7のhelloアクションを参考にして、2つ目のアクションgoodbyeを追加しましょう。このアクションは、「goodbye, world!」というテキストを表示します。リスト 1.9のルーティングを編集して、ルートルーティングの割り当て先をhelloアクションからgoodbyeアクションに変更します (図 1.17)。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def hello
    render html: "¡Hola, mundo!"
  end

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

1.5.3 演習

1.1.3.4.1と同じ変更を行い、本番アプリでも「hola, mundo!」を表示できるようにしてください。
 1.3.4.1と同じ変更を行う

$ git status
$ git commit -a -m "Change hola,mundo"
$ git push
$ git push heroku

2.1.3.4.1と同様、ルートへのルーティングを変更してgoodbyeアクションの結果が表示されるようにしてください。またデプロイ時には、Git pushのmasterをあえて省略し、git push herokuでデプロイできることを確認してみてください。
 1.3.4.3と同じ変更を行う

$ git status
$ git commit -a -m "Change goodbye"
$ git push
$ git push heroku

1.5.4 演習

1.heroku helpコマンドを実行し、Herokuコマンドの一覧を表示してみてください。Herokuアプリのログを表示するコマンドはどれですか?
 heroku logs

2.上の演習で見つけたコマンドを使って、Herokuアプリの最近のログ (log) を調べてみましょう。直近に発生したイベントは何でしたか? (このログを調べるコマンドを覚えておくと、本番環境の不具合を見つけるときに役立ちます)
 2020-06-26T08:59:30.522077+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=immense-taiga-66301.herokuapp.com request_id=b8b24da9-1231-4cc7-aace-9adcd50967b3 fwd="223.134.125.162" dyno=web.1 connect=0ms service=13ms status=200 bytes=143 protocol=https

メモ

rails newを実行すると、ファイル作成後にbundle installコマンドが自動的に実行される

エラーが出た時にどうにかしようとしてどうにもならなくなった時に何度かお世話になったブランチ削除

# ブランチでミスがあった場合
$ git checkout -b topic-branch
$ <ファイルを作成したり編集したり削除したり...>
$ git add -A
$ git commit -a -m "Make major mistake"
$ git checkout master
$ git branch -D topic-branch
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSでデプロイしちゃおうってわけ(AWS登録補足編)

どうもこんにちは。
今日は暑いですね。
そろそろ転職の準備をしなければいけない段階に入りました。:runner_tone2:

個人アプリ実装って難しいですね。
何作りたいとか無いですが、自分のスキルを示すには必要なもの。
でもありきたりなもの作っても意味ないし、複雑すぎても間に合わないし。
うーん悩みどころですね。

話がそれました。

今回はAWSの登録が済んだということでリージョンの編集です。

1そもそもリージョンってなんぞや

そうですよね。
カタカナって難しいですよね。

 リージョンとは== データセンターが存在する独立した地域

わかりませんねぇ。
うーん。

カリキュラムによると

AWSの物理的なサーバの場所を指定するものです

こっちのがなんとなくピンとくるな!!

リージョンは世界各地に10箇所以上あるらしく、そのうちの一つが東京にあるとのこと。

なのでこのリージョンを東京に設定すれば良いのです。

スクリーンショット 2020-06-26 17.29.48.png

※おそらく最初はシンガポールとかになっているはず。

ここでちゃんと東京に設定しておかないとこの後のEC2に影響が出るので意外と大事なとこなのよっ!!:fist_tone1:

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

railsでgoogle認証を実装するときにハマったこと

今回は、自分がrailsでgoogle認証を実装するときにハマったことをまとめたので参考にでも。
自分がGoogle認証を実装するときに参考にした記事 ↓
[Rails] Facebook/Twitter/Googleでのユーザー登録をDevise & Omniauthを使って爆速で実装する

エラー 400: invalid_request Missing required parameter: client_id

まず1つ目。グーグル認証のページでアカウントを選択肢して認証しようとしたときに出たエラーです。
client_idがないと言われました。
原因は2つあり
①スペースを入れていた
②.envを使わずそのままキーを入れていたこと

①スペース

devise.rb
config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'] ,ENV['GOOGLE_CLIENT_SECRET'], skip_jwt: true

から

devise.rb
config.omniauth :google_oauth2,ENV['GOOGLE_CLIENT_ID'],ENV['GOOGLE_CLIENT_SECRET'],skip_jwt: true

に変更しました。スペースがいらなかったみたいです。参考サイトではスペースはありました。

②.envを使わずそのままキーを入れていたこと
これは他のサイトを見る限りそのままでも行けた人がいるみたいですが僕の環境ではだめでした。
どうしても解決しない人はgem 'dotenv-rails'をいれてやってみてください。

メール認証がされていません

その次に出たのがこのエラー
普通にやるとメール認証がされていませんと表示されてしまいます。これは

qiita.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  # callback for google
  def google_oauth2
    callback_for(:google)
  end

  # common callback method
  def callback_for(provider)
    @user = User.from_omniauth(request.env["omniauth.auth"])
    @user.skip_confirmation!   ←これと
    @user.save!                ←これ!
    if @user.persisted?
      sign_in_and_redirect @user, event: :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
    else
      session["devise.#{provider}_data"] = request.env["omniauth.auth"].except("extra")
      redirect_to new_user_registration_url
    end
  end

  def failure
    redirect_to root_path
  end

end

@user.skip_confirmation!
@user.save!
をコントローラーに入れることで解決しました。

ぷち宣伝

公開日記というアプリを作りました。日記を公開できるアプリです(公開しないことも可)使っている人が僕しかいません(泣)。ほぼ毎日更新しているのでみてください。お願いします。

URL: https://public-diary.herokuapp.com/

まとめ

実は僕はいままで4回くらいsns認証を実装しようとし失敗しを繰り返しています。今回始めて出来たのですができたときはかなり嬉しかったです。ここまで見てくださりありがとうございました。

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

[AWS RDS][Rails]環境構築

これは何

Railsでアプリを作成中、データベースをRDSに切り替えました。
Qiitaの記事などでRDSの作成手順はあるのですが、その後のRailsのデータベースとして設定していくのにハマったので備忘録として残します。

バージョン

Rails 5.2.4.2
MySQL 5.6.4

RDS構築

私はUdemyの教材を参考に作成しましたが、
こちらの記事を参考にすれば問題ないかなと思います。
(DB・サーバー構築編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで

設定

database.ymlの記述を変えていくのですが、そこにパスワード などを直接記入することはセキュリティ上問題なので、credentials.ymlを使っていきます。

credentials.yml
rds:
  DATABASE_USERNAME: *****
  DATABASE_PASSWORD: ターミナルからRDSに接続するときのパスワード
  DATABASE_HOST: RDSのエンドポイント

RDSのエンドポイントは、AWSコンソールのRDSのデータベースをクリックして、下にスクロールするとあります。

続いて、database.ymlの変更

database.yml
production:
  <<: *default
  database: アプリ名_production
  username: <%= Rails.application.credentials.rds[:DATABASE_USERNAME] %>
  password: <%= Rails.application.credentials.rds[:DATABASE_PASSWORD] %>
  host: <%= Rails.application.credentials.rds[:DATABASE_HOST] %>
  socket: /var/lib/mysql/mysql.sock

終わったら、プッシュアンドデプロイ。

ターミナルからRDSに接続し、

mysql> show tables from アプリ名_production;
mysql>  select * from アプリ名.users;

などで中身を確認してみましょう!
反映されていますかね〜。

私はRDSに切り替えるのにずっと検索し続け、1日かかりました、、、

何はともあれ以上です!
ありがとうございました!

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

Rspecではデフォルトでviewテンプレートがレンダリングされない

長年minitestを使っていて、rspecを書くことになったのですが、rspecだとコントローラのテストを書く時にデフォルトではviewファイルがレンダリングされない事を知らず。本番で変数がnilでバグが出るという現象に遭遇しました。

rspecでは明示的にrender_viewsを呼ぶことでviewテンプレートの内容もテストする事ができます。

require "spec_helper"

describe RecordsController do
  render_views

  describe "GET index" do
    # ...
  end
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails: マイグレーションの戻し方

ご参考までに。

マイグレーションの状態を見る

upと表示されるのが実行済み、downは未実行です。

% bin/rails db:migrate:status

database: blog_rails6_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20191031052351  Create users
   up     20191031053247  Create entries
   up     20191031053324  Create tags
   up     20191031053328  Create taggings
   up     20191116013349  Create stars

1つロールバック

% bin/rails db:rollback
% bin/rails db:migrate:status

database: blog_rails6_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20191031052351  Create users
   up     20191031053247  Create entries
   up     20191031053324  Create tags
   up     20191031053328  Create taggings
  down    20191116013349  Create stars

特定のバージョンまで全部ロールバック

% bin/rails db:migrate VERSION=20191031053247
% bin/rails db:migrate:status

database: blog_rails6_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20191031052351  Create users
   up     20191031053247  Create entries
  down    20191031053324  Create tags
  down    20191031053328  Create taggings
  down    20191116013349  Create stars

特定のバージョンを1つ抜く

% bin/rails db:migrate:down VERSION=20191031053328
bin/rails db:migrate:status

database: blog_rails6_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20191031052351  Create users
   up     20191031053247  Create entries
   up     20191031053324  Create tags
  down    20191031053328  Create taggings
   up     20191116013349  Create stars

特定のバージョンのマイグレーションを1つ実行するには、db:migrate:up VERSION=バージョン とします。

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

VScodeを初めて使うRailsエンジニアへ

はじめに

エディタをVScodeに変更したRailsエンジニアのために、作業が捗るVScodeの設定をまとめてみました。
VScodeには非常に便利な拡張機能がありますが、意図しない設定まで入るブラックボックスなので、設定ファイルをカスタマイズしました。

実行環境

この記事は以下の動作環境で動作確認しています。

ruby (2.7.1)
rails (6.0.3)
Vscode
MacBook Pro

1. どうやってカスタマイズするの?

VScodeをインストール時に、メジャーな言語の設定ファイルを既に入っており、言語ごとの設定は専用のファイルで設定します。(Rubyの場合はruby.json)
言語に依存しない設定はsettings.jsonで設定します。

1-1. 設定ファイル(setting.json)の開き方

VScode上でCommand + ,と打つと設定画面が出てきます。
右上にいくつかアイコンがあり、設定を開く(JSON)とあるのでクリックするとsettings.jsonが開きます。

1-2. 設定ファイル(ruby.json)の開き方

VScode上でCommand + Shift + Pと打つとコマンドパレットが出てきます。
User snippetsで検索して出てきたConfigure User Snippetsを選択して、
次に出てきたウィンドウでrubyと検索して出てきたruby.jsonを選択すると設定が開きます。

2. 設定内容

2.1 拡張機能のRubyをインストール

カスタマイズと言いましたが、Rubyの拡張機能だけは入れてください?
VScodeの左側にある拡張機能のアイコンをクリックし、Rubyで検索して一番上にある拡張機能をインストールを押すだけでOKです。

2.2 pryと打つとbinding.pryと変換する

Railsで開発していると誰もが使用するbinding.pry(デバッグ)。ただ毎回これを全て打つのは面倒&タイポするので予測変換の設定をします。
設定方法は簡単で、ruby.jsonに下記を記載するだけです。

"prefix"の値が変換前の文字、"body"が予測変換したい文字です。
もし"prefix"の値を"pry"から"bin"に変更すると"bin"と打つとbinding.pry に変換されます。

settings.json
"Debug Console": {
  "prefix": "pry",
  "body": "binding.pry\n",
  "description": "A runtime developer console"
}

画像に alt 属性が指定されていません。ファイル名: binding_pry.gif

2.3 HTMLのタグを自動補完する

RailsでViewのコードを書くにはhtml.erbファイルを使用します。
などのタグを全て打ちたくないので、div + tabキー でタグを補完してくれるようにします。下記の設定を
settings.jsonに追加します。

settings.json
{
 "emmet.includeLanguages": {
    "erb": "html",
 },
}

2.4 関数の定義元へジャンプ

Commandを押しながら関数をクリック、定義元にジャンプできる非常に便利な設定です。
Command + Shift + P でコマンドパレットを開き、keyboardで出てくるkeybinding.jsonに下記を記載します。

keybinding.json
[
  {
    "key": "cmd+d",
    "command": "editor.action.goToDeclaration",
    "when": "editorTextFocus"
  }
]

2.5 ターミナルからVScodeを開く

Command + Shift + P でコマンドパレットを開き、shellで出てくる shell command:install 'code' command in PATH をクリック。
ターミナルでcode . と打つとカレントディレクトリのファイルを開くことができます。

2.6 末尾の改行と空白を自動で削除

末尾に改行がないものには改行を追加。末尾の不要な改行・空白は自動で削除する設定です。
Command ,で設定を開き、trimで検索して全ての項目にチェックをする。

画像に alt 属性が指定されていません。ファイル名: 末尾改行・空白-1024x430.png
おわりに
他にもいろいろな設定があるので、好みに合わせて、拡張機能を追加したり、settings.jsonに設定を追加したりしてみてください。

参考までに私のsettings.jsonを添付しておきます。
右端で折り返す、スクロールを止める、オートセーブ当たりも入れておいた方が快適になると思います。

setting.json
{
  "files.autoSave": "onFocusChange", //ファイルのオートセーブ
  "editor.formatOnSave": true,
  "editor.tabSize": 2, //1つのタブに相当するスペースの数
  "editor.detectIndentation": false,
  "emmet.variables": {},
  "emmet.triggerExpansionOnTab": true,
  "ruby.rubocop.onSave": false,
  "html.format.endWithNewline": true,
  "html.format.indentInnerHtml": true,
  "emmet.includeLanguages": {
    "erb": "html",
  },
  "window.zoomLevel": 0,
  "ruby.intellisense": "rubyLocate",
  "diffEditor.renderSideBySide": false, // Git の差分を行内に表示
  "editor.wordWrap": "on", // 右端で折り返す
  "editor.minimap.renderCharacters": false, // ミニマップを簡略化
  "editor.links": true, // リンクをクリック可能に
  "indentRainbow.colors": [
    "rgba(255,255,64,0.07)",
    "rgba(127,255,127,0.07)",
    "rgba(255,127,255,0.07)",
    "rgba(79,236,236,0.07)"
  ],
  "editor.scrollBeyondLastLine": false, //下限でスクロールをストップさせる
  "editor.formatOnPaste": true, // ペースト時に自動でフォーマット
  "breadcrumbs.enabled": true,
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true,
  "files.trimFinalNewlines": true, // ファイルの保存時に末尾を改行
  // Reactの設定
  "emmet.includeLanguages": {
    "javascript": "javascriptreact",
    "vue-html": "html"
    // },
    "emmet.syntaxProfiles": {
      "html": {
        "attr_quotes": "single"
      },
      "jsx": {
        "self_closing_tag": true
      }
    }
  }
}



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

[エラー]自動デプロイ実行時のrbenv: ruby 2.5.1 is not installedot〜に関して

はじめに

今回の投稿は私が自動デプロイを実行した時にエラーにハマったので、その内容を共有させていただきます。

エラー内容

[Deprecation Notice] Future versions of Capistrano will not load the Git SCM
plugin by default. To silence this deprecation warning, add the following to
your Capfile after `require "capistrano/deploy"`:

    require "capistrano/scm/git"
    install_plugin Capistrano::SCM::Git

00:00 rbenv:validate
      WARN  rbenv: ruby 2.5.1 is not installed or not found in $HOME/.rbenv/versions/ruby 2.5.1 on 54.95.87.53

仮説を立てる

1. require "capistrano/scm/git"
require〜という記述からCapfileに異常があると仮説。

2. WARN rbenv: ruby 2.5.1 is not installed〜
ruby 2.5.1 is not installedという記述からruby2.5.1のインストールがされていない、またローカル環境とのverに差異があると仮説。怪しいのはdeploy.rbか...?

仮設検証 Capfile

require "capistrano/setup"
require "capistrano/deploy"
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git

Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

特に異常なし。

仮設検証 ver確認

ローカル開発環境と本番環境(EC2)内でruby -vを実行したが問題なし。

仮設検証 deploy.rb

deploy.rb
# config valid only for current version of Capistrano
# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock '3.14.1'

# Capistranoのログの表示に利用する
set :application, 'chat-space'

# どのリポジトリからアプリをpullするかを指定する
set :repo_url,  'git@github.com:ken-sasaki-222/chat-space.git'

# バージョンが変わっても共通で参照するディレクトリを指定
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')

set :rbenv_type, :user
set :rbenv_ruby, 'ruby2.5.1' #ここに注目

# どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
                  keys: ['~/.ssh/test_key.pem'] 

# プロセス番号を記載したファイルの場所
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }

# Unicornの設定ファイルの場所
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5

# デプロイ処理が終わった後、Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end

rubyのverに問題はなさそう。と思いきや...
ver指定の箇所が'ruby 2.5.1'になっている!

正しくは'2.5.1'でOK!
修正すると。

deploy.rb
#省略

set :rbenv_type, :user
set :rbenv_ruby, '2.5.1' #ここに注目

#省略

これでローカル環境のターミナルにてbndle exec cap production deployを実行すると
無事自動デプロイが走りました。

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

Rails6で lib ディレクトリの自作クラスを使用する

自作クラスを作成し利用する方法、
今回はroot/lib配下に作る方法をご紹介します。

環境

rails 6.0.3

application.rbの設定

application.rb
module Myapp
  class Application < Rails::Application
    config.load_defaults 6.0
    config.paths.add 'lib', eager_load: true #これを追加
  end
end

lib配下をautoload_pathsに追加します。
autoload_pathsについてはこちら

lib配下の構成

lib
 ├── assets
 ├── asks
 └── utils
     └── hoge.rb

utils/hoge.rbを作成しまいした。
分かりやすい命名にしましょう。

hoge.rbの中身

hoge.rb
class Utils::Hoge
end

もしくは

hoge.rb
module Utils
  class Hoge
     def greeting
         'hello'
     end
  end
end

親ディレクトリの名称をネームスペースとして、クラスを定義しましょう。
こうすることでautoload_pathsの規則に乗っ取って以下のように呼び出せます。

application_controller.rb
class ApplicationController < ActionController::Base
   hoge = Utils::Hoge.new
   hoge.greeting
   #=> hello  
end

最後に

この記事を書いてる際以下のような投稿を発見しました。
(リサーチ不足が露呈した、、、)

autoload_pathsを修正して謎エラーをなくした話

Rails Guaidによると
「Rails5より前ではlib/以下をautoload_pathsに含めることがよく行われていたが、現在はappフォルダ以外の場所にコードを置いてautoload対象にするのは勧めない」となっています。
本番環境特有のエラーが発生するかもしれないとのこと。

app配下はautoload_pathsにデフォルトで入っているので、
そちらを使うのが良さそう。

じゃあなんでlibディレクトリは存在してるんだ?
開発上手な人はうまく使い分けているのかな。

新たな疑問が生まれたところで、今回は以上です。
日々精進

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