20190228のRailsに関する記事は22件です。

railsでIndex name 'xxxxxxxxxxxxxxxxxxx' on table 'テーブル名' is too long; the limit is 64 characters

経緯

railsのmigrationで
Index name 'xxxxxxxxxxxxxxxxxxx' on table 'テーブル名' is too long; the limit is 64 charactersと怒られる
テーブル名、カラム名などなどが長くなり、自動付与されるインデックス名が長くなりすぎることが原因

対応

t.references :my_field, index: { name: 'my_index_name' }
でindex名を指定してやればOK!

add_indexでindexを別で設定する場合は以下の記事を参考
https://qiita.com/ezawa800/items/9a63a96fb36a7c1de04d

参考

http://stackoverflow.com/questions/28727240/migrations-t-references-doesnt-allow-index-name-to-be-specified

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

Railsチュートリアルに再挑戦する

前に挫折してしまったRailsチュートリアルに再挑戦してみようと思います。

過度に完璧主義にならずに、適度にサボりながら周回を重ねていこうと思います。

testは後回しにしたり、課題を後回しにしたり、後回しでもいいと言われたところは後回しにしたり。

まずは一周して全体を掴んでいこうと思います。

1周目はCloud9で、2周目以降はローカル開発に挑戦していきたいですね。

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

Rails開発の初期設定で参考になった記事まとめ

Railsのインストール

過去の記事をご覧ください(Railsインストール)

MySQLに変更する方法

過去の記事をご覧ください(DBをMySQLに変更)

日本語化

Rails5からはapplication.rbでは設定できないので注意しよう。新しいファイルを追加して以下のように設定しよう。ja.ymlに関しては同じように設定できる。

initializers/locals.rb
I18n.config.available_locales = :ja
I18n.default_locale = :ja

Railsの基本的な概念

※viewは対応するコントローラーのアクションで定義された変数が使えてRubyが埋め込めることがわかればとりあえずいいと思うので省略。

GitHub関連

GitHubの使い方はこのあたりが良かった。ssh通信の公開鍵の登録についてはこのあたりが参考になった。また、パスワードなどの機密情報が書かれているファイルは、GitHubで公開することは避けよう(.gitignoreをいじれば同期するものを制限できる)。

Bootstrap

Bootstrapは使い方はこのあたり、導入の仕方はこのあたりが参考になった。

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

hevens_doorを使ってみた

はじめに

Rails/Rubyのコミッターであるa_matsudaさんが制作されているheavens_doorのチュートリアル記事です

実際のデモ

実際にはこんな感じで動作します

heavens_door.gif

なお、実際に作ったものはこちら

チュートリアル

rails new

まずは、rails newheavens_doorを試すサンプルアプリを作ります

rails new heavens_door

capybaraの導入

次に、capybaraを導入します

Gemfile
gem 'capybara', '>= 2.15', group: :development

そのあと、bundle installを実行します

bundle install

テスト用CRUD作成

テストするためのCRUDを作成します

rails g scaffold post title content

その後、rails db:migrateを実行します

rails db:migrate RAILS_ENV=test

heavens_doorの導入

heavens_doorを導入したいと思います!

Gemfileheavens_doorを追加します

Gemfile
gem 'heavens_door', group: :development

bundle installgemをインストールします

bundle install

heavens_doorを使う

最後に、heavens_doorを使ってみましょう!

まず、test/intgration/posts_test.rbを作成し、以下のようにします

test/intgration/posts_test.rb
require 'capybara/rails'
require 'capybara/minitest'

class ActionDispatch::IntegrationTest
  include Capybara::DSL
  include Capybara::Minitest::Assertions

  def heavens_door
  end
end

その後、rails sでローカルサーバを起動し、localhost:3000/postsにアクセスします

rails s

あとは画面右上に表示されているボタンをクリックするとUI操作の記録がはじまります

適当に操作したあと、バインダーマークをクリックするとUIテストのコードがクリップされます

あとは、test/intgration/posts_test.rbにクリップしたコードを貼り付けます

test/intgration/posts_test.rb
require 'capybara/rails'
require 'capybara/minitest'

class ActionDispatch::IntegrationTest
  # Make the Capybara DSL available in all integration tests
  include Capybara::DSL
  # Make `assert_*` methods behave like Minitest assertions
  include Capybara::Minitest::Assertions

  # Reset sessions and driver between tests
  # Use super wherever this method is redefined in your individual test classes
  def heavens_door
    scenario 'GENERATED' do
        visit '/posts'

        click_link 'New Post'

        fill_in 'Title', with: 'test'
        fill_in 'Content', with: 'aaaaaaaaaaaaaaaaaaaaaaaaa'
        click_button 'Create Post'

        click_link 'Back'
    end    
  end
end

最後に、rails testを実行してください

rails test

テストが実行されていればOKです!

参考

amatsuda/heavens_door

teamcapybara/capybara#using-capybara-with-minitest

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

heavens_doorを使ってみた

はじめに

Rails/Rubyのコミッターであるa_matsudaさんが制作されているheavens_doorのチュートリアル記事です

実際のデモ

実際にはこんな感じで動作します

heavens_door.gif

なお、実際に作ったものはこちら

チュートリアル

rails new

まずは、rails newheavens_doorを試すサンプルアプリを作ります

rails new heavens_door

capybaraの導入

次に、capybaraを導入します

Gemfile
gem 'capybara', '>= 2.15', group: :development

そのあと、bundle installを実行します

bundle install

テスト用CRUD作成

テストするためのCRUDを作成します

rails g scaffold post title content

その後、rails db:migrateを実行します

rails db:migrate RAILS_ENV=test

heavens_doorの導入

heavens_doorを導入したいと思います!

Gemfileheavens_doorを追加します

Gemfile
gem 'heavens_door', group: :development

bundle installgemをインストールします

bundle install

heavens_doorを使う

最後に、heavens_doorを使ってみましょう!

まず、test/intgration/posts_test.rbを作成し、以下のようにします

test/intgration/posts_test.rb
require 'capybara/rails'
require 'capybara/minitest'

class ActionDispatch::IntegrationTest
  include Capybara::DSL
  include Capybara::Minitest::Assertions

  def heavens_door
  end
end

その後、rails sでローカルサーバを起動し、localhost:3000/postsにアクセスします

rails s

あとは画面右上に表示されているボタンをクリックするとUI操作の記録がはじまります

適当に操作したあと、バインダーマークをクリックするとUIテストのコードがクリップされます

あとは、test/intgration/posts_test.rbにクリップしたコードを貼り付けます

test/intgration/posts_test.rb
require 'capybara/rails'
require 'capybara/minitest'

class ActionDispatch::IntegrationTest
  # Make the Capybara DSL available in all integration tests
  include Capybara::DSL
  # Make `assert_*` methods behave like Minitest assertions
  include Capybara::Minitest::Assertions

  # Reset sessions and driver between tests
  # Use super wherever this method is redefined in your individual test classes
  def heavens_door
    scenario 'GENERATED' do
        visit '/posts'

        click_link 'New Post'

        fill_in 'Title', with: 'test'
        fill_in 'Content', with: 'aaaaaaaaaaaaaaaaaaaaaaaaa'
        click_button 'Create Post'

        click_link 'Back'
    end    
  end
end

最後に、rails testを実行してください

rails test

テストが実行されていればOKです!

参考

amatsuda/heavens_door

teamcapybara/capybara#using-capybara-with-minitest

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

【OmniAuth + Devise】Twitterのログイン認証をテストする方法【Rspec】

はじめに

仕事でAuth認証のspecを書く場面があったので、いろいろハマったことも含め簡潔に書いていきたいと思います。

【実行環境】
・ Rails 5.1.4
・ RSpec 3.7
・ Ruby 2.4.3

ざっくり実装の手順

  1. Rspecのセットアップ
  2. モックの作成
  3. Controllerの認証テスト

【前提】omniauthのルート設定

複数モデルで実装する方も多いと思うので、
Omniauthの認証処理はAuthenticationsControllerでやるとします。

config/routes.rb
  get "auth/:provider" => "authentications#new", as: :new_authentication
  get "auth/:provider/callback" => "authentications#create", as: :create_authentication

参考: https://github.com/plataformatec/devise/wiki/OmniAuth-with-multiple-models

テストするもの

・Authが正常に渡ってきたときの処理(createアクション)
・Authが渡って来なかったときのエラーハンドリング(createアクション)
・Auth認証に失敗した時の処理(failureアクション)

app/controllers/authentications_controller.rb
class AuthenticationsController < ApplicationController 
  # get "auth/:provider" 
  # def new  ← omniauthにより、newアクションは自動生成される
  # end

  #  get "auth/:provider/callback"
  def create
    raise "request.env[omniauth.auth]がありません" if auth_params.nil?
    @social_profile = SocialProfile.new.set_value(auth_params)
    @user = User.new(emial: @social_profile.email)
    if @user.save
      @social_profile.save!
      redirect_to edit_uer_registratiion_url
    else
      redirect_to new_user_registration_path
    end
  end

  # callbackに失敗したときに呼ばれるアクション
  def failure
    redirect_to user_setting_social_profiles_path if current_user
  end

  private
    # ユーザー情報の入った
    def auth_params
      request.env["omniauth.auth"]
    end
end

肝となるのはやはりrequest.env["omniauth.auth"]です。
今回テストすべきなのはauth/:provider/callbackを叩いた時に正常にユーザーデータが渡ってくるかなので、ここでいう、createアクションのspecを主に書いていこうと思います。

Rspecのセットアップ

まずはOmniAuthをテストモードに変えておきましょう。
また、deviseのヘルパーを使う場合は、それぞれ設定しておきます。

spec/rails_helper.rb
# OmniAuthをテストモードに変更
OmniAuth.config.test_mode = true

RSpec.configure do |config|
  # FactoryBotの記述省略
  config.include FactoryBot::Syntax::Methods
  # deviseで使うヘルパー
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::IntegrationHelpers, type: :request
end

テストで用意するデータ

ユーザーデータのハッシュが入ってるのが、request.env["omniauth.auth"]なので、
そのユーザーデータを擬似的に作ってテストしてあげればOK。

本来request.env["omniauth.auth"]にどんなハッシュが渡ってくるかは以下を参考に↓
https://github.com/arunagw/omniauth-twitter#authentication-hash

そのために、認証用のモックを作っていきます。

モックの作成

request.env["omniauth.auth"]に入れるモックを作成しましょう。

どこでも使うのでspec/rails_helper.rbに記述してもいいですが、結構長いので今回はspec/support/omniauth_mocks.rbに書いて最後にincludeするようにします。

spec/support/omniauth_mocks.rb
module OmniauthMocks
  def twitter_mock
    OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new({
      "provider" => "twitter",
      "uid" => "123456",
      "info" => {
        "name" => "Mock User",
        "image" => "http://mock_image_url.com",
        "location" => "",
        "email" => "mock@example.com",
        "urls" => {
          "Twitter" => "https://twitter.com/MockUser1234",
          "Website" => ""
        }
      },
      "credentials" => {
        "token" => "mock_credentails_token",
        "secret" => "mock_credentails_secret"
      },
      "extra" => {
        "raw_info" => {
          "name" => "Mock User",
          "id" => "123456",
          "followers_count" => 0,
          "friends_count" => 0,
          "statuses_count" => 0
        }
      }
    })
  end
end
spec/rails_helper.rb
RSpec.configure do |config|
  config.include OmniauthMocks
end

コントローラで認証処理をテストする

コールバックが呼ばれたときに、以下の内容をテストします。
・ authが渡ってこなければエラーを起こす
・ authが渡ってこれば各モデルが作成されること
・ authにemailが含まれてなければ再度認証画面にリダイレクトさせること

app/controllers/authentications_controller.rb
class AuthenticationsController < ApplicationController 
  #  get "auth/:provider/callback"
  def create
    raise "request.env[omniauth.auth]がありません" if auth_params.nil?
    @social_profile = SocialProfile.new.set_value(auth_params)
    @user = User.new(emial: @social_profile.email)
    if @user.save
      @social_profile.save!
      redirect_to edit_uer_registratiion_url
    else
      redirect_to new_user_registration_path
  end

  private
    # ユーザー情報の入った
    def auth_params
      request.env["omniauth.auth"]
    end
  end

Rspec↓

spec/controllers/authentications_controller_spec.rb
require 'rails_helper'

RSpec.describe AuthenticationsController, type: :controller do
  before { request.env["omniauth.auth"] = twitter_mock }
  subject { get :create, params: { provider: "twitter" } }

  it "oauthが渡ってこない場合エラーになる" do
    request.env["omniauth.auth"] = nil
    expect { subject }.to raise_error("request.env[omniauth.auth]がありません")
  end

  context "emailがある場合" do
    it "新規作成" do
      expect { subject }.to change { User.count }.from(0).to(1)
      expect { subject }.to change { SocialProfile.count }.from(0).to(1)
      expect(subject).to redirect_to edit_user_registration_url
    end
  end

  context "emailがない場合" do
    it "登録画面へリダイレクト" do
      request.env["omniauth.auth"]["info"]["email"] = nil
      expect(subject).to redirect_to new_user_registration_path
    end
  end
end

①request.env["omniauth.auth"]に先ほど作ったユーザーデータの入ったハッシュ型のモック(twitter_mockd)が入る。

②一つ目のexample → request.env["omniauth.auth"] = nilとすることで、authが渡って来なかったと判断し、エラーを吐く。

③2つ目のexample → auth_paramsにモックが入ってるので、欲しいデータがしっかり入っていれば正常にsave(作成)される。

④3つ目のexample → request.env["omniauth.auth"]["info"]["email"] = nilで、モックのeamilを空にする。この状態でリクエストを送ればモデルは作成されずリダイレクトされる.

認証失敗時のテスト

callbackが失敗した時、どこにリダイレクトすればいいのかはconfig/initializers/omniauth.rbで設定できます。

config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, Settings.oauth.twitter.consumer_key, Settings.oauth.twitter.consumer_secret   
  on_failure do |env|
    AuthenticationsController.action(:failure).call(env) ##ここで設定
  end 
end

今回はAuthenticationsControllerfailureアクションが呼ばれるように設定したので、AuthenticationsControllerでテストしてみることにします。

app/controllers/authentications_controller.rb
class AuthenticationsController < ApplicationController
  # ...省略

  def failure
    redirect_to user_setting_social_profiles_path if current_user
  end
end

じゃあコールバックを失敗させるにはどうすればいいかというと、失敗用のモックをまた別に作ってあげる必要があります。

spec/support/omniauth_mocks.rb
module OmniauthMocks
  # ...省略

  def twitter_invalid_mock
    OmniAuth.config.mock_auth[:twitter] = :invalid_credentails
  end
end

このモックを使ってコールバックを叩けばfailureにリダイレクトさせることができます。
参考: https://github.com/omniauth/omniauth/wiki/Integration-Testing#mocking-failure

コールバック失敗時のテストコードを書いてみる

早速 failureアクションのテストがしたいから、

get :failure, params: { provider: "twitter" }

みたいな感じに書いてみましたが、「そんなルートねぇよ!」と怒られました。。

なぜなら、failureは、コールバックに失敗した時にしか呼ばれないからです。

僕はこれにハマってしまい、なぜルートがないのに呼ばれるのだろう?と思っていたのですが、どうやらomniauthの方でcallbackに失敗したら自動的で呼ばれるようになっているらしい。

コードの中身: https://github.com/omniauth/omniauth/blob/c2380ae848ce4e0e39b4bb94c5b8e3fd0a544825/lib/omniauth/builder.rb#L22
Github : https://github.com/omniauth/omniauth/wiki/Integration-Testing

Github(翻訳): https://techracho.bpsinc.jp/hachi8833/2017_05_22/40297

というわけで、コールバックのURLを叩きにいって、失敗させて上げる必要があります。
今回コールバックのURLは

config/routes.rb
get "auth/:provider/callback" => "authentications#create", as: :create_authentication

となっているため、Authentications#createにGETリクエストを投げてテストしてみました。

spec/controllers/authentications_controller_spec.rb
require "rails_helper"

RSpec.describe "omniauth", type: :request do
  # ...省略

  describe "GET #failure" do
    let(:user) { create(:user) }
    before { request.env["omniauth.auth"] = twitter_invalid_mock }
    subject { get :create, params: { provider: "twitter" }

    it "current_userが存在する" do
      sigin_in user
      expect(subject).to redirect_to user_setting_social_profiles_path
    end
    it "current_userが存在しない" do
      expect(subject).to render_template :failure
    end
  end
end

と、書きたいところですが、これではfailureアクションにはリダイレクトしてくれませんでした。
また、テスト用のparams(:invalid_credentails)をアクション内で整形してしまいエラーを吐いてしまいます。

これでは明示的にfailureアクションに飛ばすしか方法がありません。

アクションを介さずに直接リダイレクトするには、spec/requests以下に書きましょう。

spec/requests/authentications_spec.rb
require "rails_helper"

RSpec.describe "omniauth", type: :request do
  describe "GET #failure" do
    before do
      Rails.application.env_config["omniauth.auth"] = twitter_invalid_mock
    end
    subject { get "/auth/twitter/callback" }

    it "current_userが存在する" do
      sigin_in user
      expect(subject).to redirect_to user_setting_social_profiles_path
    end
    it "current_userが存在しない" do
      expect(subject).to render_template :failure
    end
  end
end

これで無事通すことができました。
参考: https://qiita.com/Apuruny/items/38dc94628f7b52bd172e

まとめ

Twitter認証の仕組みなんてそもそもわからないし、ましてやテストコードをかけとは何事だと思ってましたが、いろんな記事に恵まれて無事実装することができました。

全て動作確認をしてるわけではないので、コピペする際はご注意ください(m_ _m)

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

[CarrierWave]RSpec実行後の画像ファイルを削除する

はじめに

RSpecでテストを何度も実施していたら画像ファイルが膨大に保存されており、自動で削除されるように設定したのでメモします。

参考にしたサイト

How to: Cleanup after your Rspec tests
Rspecのcarrierwaveを実行した後のファイルを削除
画像周りの扱い方
CarrierWave + RSpec ディレクトリ問題

手順

1. 環境

ruby                  : 2.5.1
rails                 : 5.2.2
device                : 4.6.1
carrierwave           : 1.3.1
rspec-rails           : 3.8.2

2. development時とtest時で画像が保存されるディレクトリを分ける

Carrierwaveをインストールした際にrails g uploader Photoをしてapp/uploaders/photo_uoloader.rbが作成されているので、ここに画像の保存場所を設定します。

app/uploaders/photo_uoloader.rb
class PictureUploader < CarrierWave::Uploader::Base
# 省略
def store_dir
  if Rails.env.test?
    "uploads_#{Rails.env}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  else
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end
# 省略

3. テスト終了後にファイルを削除する

spec/rails_helper.rbに以下を追加します。

spec/rails_helper.rb
RSpec.configure do |config|
# 省略
config.after(:all) do
    if Rails.env.test?
      FileUtils.rm_rf(Dir["#{Rails.root}/public/uploads_#{Rails.env}/"])
    end
  end
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsでDBをMySQLに変更する方法(Ubuntu)

MySQLの設定

MySQLのインストール

以下のコマンドを順に実行。

$ sudo apt update
$ sudo apt install mysql-server mysql-client

これでMySQLのインストールが完了しました。

Railsで使うユーザーの設定

以下を実行しRailsで使うMySQLのユーザー名(user)とパスワード(password)を設定する。Railsには開発環境(development)、テスト環境(test)、本番環境(production)がある。それぞれに対してDBが割り当てられるので3つのユーザーを作るほうが管理が楽だと思う(以下のコマンドでは1人のユーザーを作っている)。

$ sudo mysql -u root -p
# パスワードを要求されるが「Enter」をおせばよい
mysql> CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';

RailsがMySQLにアクセスできるように権限を与える。特定のDBにだけ権限を絞ることができるが、この段階ではDBが生成されていないので制限をかけるのが難しいので、強めの権限を与えることにする。後にRails側の設定が終わってDBが作ってから変更することを推奨する。

 GRANT ALL ON *.* TO 'user'@'localhost';

Railsの設定

プロジェクトの作成とデーターベースの設定ファイルの編集

Railsのインストールができていない方はこちらRails new -d mysql --skip-bundleを実行することでDBをMySQLに指定してプロジェクトを作ることができる。上記のコマンドを実行したら、以下のようにファイルを編集しよう。

config/database.yml
# MySQL. Versions 5.1.10 and up are supported.
#
# Install the MySQL driver
#   gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
#   gem 'mysql2'
#
# And be sure to use new-style password hashing:
#   https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
 username: MySQLで設定したuser
  password: MySQLで設定したpassword
  socket: /var/run/mysqld/mysqld.sock
  host: localhost

development:
  <<: *default
  database: Math-Dictionary_development

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: Math-Dictionary_test

# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
#
production:
  <<: *default
  database: Math-Dictionary_production
  password: <%= ENV['MATH-DICTIONARY_DATABASE_PASSWORD'] %>

※もし、MySQLの設定で3つのユーザーを設定している場合は、それぞれの環境の設定のところに上書きして更新することができる。

bundle install のエラー対処法

次にbundle installを実行する。ここで

An error occurred while installing mysql2 (0.3.16), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.3.16' --source 'https://rubygems.org/'` succeeds before bundling.

このようなエラーが出る場合はこのエラーメッセージ通りgem install mysql2 -v '0.3.16'を実行しよう。さらに、これでもエラーが出る場合は、そのエラーメッセージの上部にインストールするべきものがないかを確認しよう。私の場合は、sudo apt-get install libmysqlclient-devを実行せよとなっていた。これでgem install mysql2 -v '0.3.16'が実行できて、無事bundle installすることができた。他にも、bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include"を実行するといける場合もあるらしい(ググって出てきただけ)。

実際にデーターベースを作成する

rake db:create

これでDBがMySQLになりました。

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

deviseを日本語化する方法の備忘録

deviseを日本語化する方法の備忘録です。

gemをインストール

gemfile
gem 'devise-i18n'
gem 'devise-i18n-views'

$bundle installを実行する。

日本語翻訳ファイルを生成

$rails g devise:views:local ja

config/locales/devise.viwes.ja.yml
ja:
  activerecord:
    attributes:
      user:
        current_password: "現在のパスワード"
        email: "メールアドレス"
        password: "パスワード"
        password_confirmation: "確認用パスワード"
        remember_me: "ログインを記憶"
    models:
      user: "ユーザ"
  devise:
    confirmations:
      new:
        resend_confirmation_instructions: "アカウント確認メール再送"
    mailer:
      confirmation_instructions:
        action: "アカウント確認"
        greeting: "ようこそ、%{recipient}さん!"
        instruction: "次のリンクでメールアドレスの確認が完了します:"
      reset_password_instructions:
        action: "パスワード変更"
        greeting: "こんにちは、%{recipient}さん!"
        instruction: "誰かがパスワードの再設定を希望しました。次のリンクでパスワードの再設定が出来ます。"
        instruction_2: "あなたが希望したのではないのなら、このメールは無視してください。"
        instruction_3: "上のリンクにアクセスして新しいパスワードを設定するまで、パスワードは変更されません。"
      unlock_instructions:
        action: "アカウントのロック解除"
        greeting: "こんにちは、%{recipient}さん!"
        instruction: "アカウントのロックを解除するには下のリンクをクリックしてください。"
        message: "ログイン失敗が繰り返されたため、アカウントはロックされています。"
    passwords:
      edit:
        change_my_password: "パスワードを変更する"
        change_your_password: "パスワードを変更"
        confirm_new_password: "確認用新しいパスワード"
        new_password: "新しいパスワード"
      new:
        forgot_your_password: "パスワードを忘れましたか?"
        send_me_reset_password_instructions: "パスワードの再設定方法を送信する"
    registrations:
      edit:
        are_you_sure: "本当に良いですか?"
        cancel_my_account: "アカウント削除"
        currently_waiting_confirmation_for_email: "%{email} の確認待ち"
        leave_blank_if_you_don_t_want_to_change_it: "空欄のままなら変更しません"
        title: "%{resource}編集"
        unhappy: "気に入りません"
        update: "更新"
        we_need_your_current_password_to_confirm_your_changes: "変更を反映するには現在のパスワードを入力してください"
      new:
        sign_up: "アカウント登録"
    sessions:
      new:
        sign_in: "ログイン"
    shared:
      links:
        back: "戻る"
        didn_t_receive_confirmation_instructions: "アカウント確認のメールを受け取っていませんか?"
        didn_t_receive_unlock_instructions: "アカウントの凍結解除方法のメールを受け取っていませんか?"
        forgot_your_password: "パスワードを忘れましたか?"
        sign_in: "ログイン"
        sign_in_with_provider: "%{provider}でログイン"
        sign_up: "アカウント登録"
    unlocks:
      new:
        resend_unlock_instructions: "アカウントの凍結解除方法を再送する"

必要に応じてメッセージを変更する。

localeの設定

config/application.rb
config.i18n.default_locale = :ja

上のコードをconfig/application.rbに記述する。
localeを設定することで日本語化できるようです。

まとめ

以上が今回私が実施したdeviseを日本語化する方法です。

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

Rails で Web API 開発(Part. 5 R(CRUD) の実装)

はじめに

 本記事は、自身が今までの Ruby on Rails で開発してきた知識 / 知見の総まとめをおこなったものです。
 「ここは、もっとこうしたほうがいいよ!こういうものがあるよ!」というようなことがあれば、随時おしらせください!
 最終的なプロダクトは、 Rails API Sample に置いておきます。

各記事

記事の構成

前回の記事

 前回は、CORS の設定を行いました。

今回の記事

 今回は、実際に CRUD のうちの R の実装をおこなっていきたいと思います。

次回の記事

 次回は、ひきつづき CRUD のうちの CUD の実装をおこなっていきたいと思います。

API 仕様書 の作成

Swagger Editor の起動

 早速実装を…!といきたいのですが、ひとまず仕様書をちゃんと作ろうということで、 Swagger Editor を扱えるようにしていきましょう。
 以下のコマンドを実行しましょう。

$ docker pull swaggerapi/swagger-editor
$ docker run -d --rm -p 80:8080 swaggerapi/swagger-editor

 おそらく、 localhost にブラウザ上からアクセスすれば Swagger Editor が起動しているのを確認できるはずです。
 画面左部に以下を記述してみましょう。 swagger の記述方法については、解説しませんので今後記述していくうえで演繹的に感じていただけたらと思います。

# This Docs Information
swagger: "2.0"
info:
  version: "0.0.1"
  title: "Rails API Sample"

schemes:
- "http"
host: "localhost:40000"
basePath: "/api"

produces:
  - application/json

paths:
  /users:
    get:
      tags:
        - "users - action"
      summary: "User 全体取得 API"
      responses:
        200:
          description: "OK"
          schema:
            type: array
            items:
              type: object
              properties:
                id:
                  type: integer
                name:
                  type: string
                created_at:
                  type: string
                updated_at:
                  type: string

  /users/{id}:
    get:
      tags:
        - "users - action"
      summary: "User 全体取得 API"
      parameters:
        - in: path
          name: "id"
          type: integer
          required: true
      responses:
        200:
          description: "OK"
          schema:
            type: object
            properties:
              id:
                type: integer
              name:
                type: string
              created_at:
                type: string
              updated_at:
                type: string

 以下のような画面になるはずです。

Screen Shot 2019-02-28 at 19.31.10.png

yaml ファイルの保存

 また念の為、この yaml ファイル は、 docs 配下 に保存しておくことにします。

API の実装

 さて、それでは実際に API を実装していきましょう。

エラー処理機構の実装

 さっそく実装を!!といきたいのですが、まずは先にエラー処理機構を整えることにしましょう。

I18n で日本語化

 Rails の I18n という機能を用いて、Message の管理をおこなっていきます。
 まずは、以下のコマンドで、デフォルトの ja.yml ファイルをダウンロードしましょう。
 Mac の場合は、 $ brew install wget とかうてば wget コマンド うてるようになるのかな?

$ wget https://raw.github.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -P config/locales/ja/default.yml

 次に、 config/application.rb に追記し、起動時に locales 配下の *.yml が読み込まれるようにします。

  # I18n の設定
  config.i18n.default_locale = :ja
  config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]

 最後に、 config/locales/ja/error.yml を作成しましょう。この部分に、各エラーの情報を記載していきます.

ja:
  errors:
    ApiErrors::FilterParamsError:
      status_code: 400
      error_code: E001
      error_description: リクエストパラメーターが異常です。
    ApiErrors::GenerateJSONError:
      status_code: 500
      error_code: E002
      error_description: JSON 生成時にエラーが発生しました。
    other:
      status_code: 500
      error_code: E999
      error_description: サーバー内でエラーが発生しました。

エラー処理機構

 app/controllers/application_controller.rb を以下のように編集しましょう。
 この部分で、エラーを処理して response を返すようにします。また、先に記述した yml ファイル を読み込むような設定もこの部分でしています.

class ApplicationController < ActionController::API
  rescue_from Exception, with: :render_error

  private

  def render_error(error)
    error_description = I18n.t("errors.#{error.class}", default: :'errors.other')
    response = {
      error_code: error_description[:error_code],
      error_description: error_description[:error_description]
    }
    render json: response, status: error_description[:status_code]
  end
end

エラークラス

 最後に、今後発生するであろうエラークラスを app/errors/api_errors.rb に定義しておきます。

module ApiErrors
  class FilterParamsError < StandardError
  end

  class GenerateJSONError < StandardError
  end
end

Model の実装

 それでは、以下のような app/models/user.rbapp/models/micropost.rb を作成しましょう。

class User < ApplicationRecord
  self.table_name = 'users'

  has_many :microposts
end
class Micropost < ApplicationRecord
  self.table_name = 'microposts'

  belongs_to :user
end

 Validation 等のビジネスロジック(ビジネスロジックとは何か…。はおいておきます…。)は、いっさいかきません。
 Rails では、よく Controller 層 / Model 層の肥大化が問題となっているので、今回は Trailblazer という gem を扱います。

Routing の設定

 それでは、 config/routes.rb を以下のように編集しましょう。

Rails.application.routes.draw do
  namespace :api do
    resources :users, only: %i[show index]
  end
end

Operation(JSON 生成層) の実装

 名付けがよくわからなかったので、とりあえず Operation(JSON 生成層)の実装をおこなっていきます。
 以下のような全ての Operation が継承をする app/concepts/apprication_operation.rb を作成します。
 ここでは、Operation で引き起こされるであろう Error について記述しておきます。ここで引き起こされた Error は、 application_controller.rb で処理されます。
 また、日付を format する関数をここに記述しておきます.

class ApplicationOperation < Trailblazer::Operation
  protected

  def handle_filter_params_error!(*)
    raise ApiErrors::FilterParamsError
  end

  def handle_generate_json_error!(*)
    raise ApiErrors::GenerateJSONError
  end

  def simple_format_time(time)
    time.strftime('%Y-%m-%d %H:%M:%S')
  end
end

 それでは、具体的に show / index method の実装をおこなっていきます。
 以下のような app/concepts/users/operation/show.rbapp/concepts/users/operation/index.rb を作成します。

class Users::Operation::Show < ApplicationOperation
  step :filter_params
  failure :handle_filter_params_error!
  step :generate_json
  failure :handle_generate_json_error!

  private

  def filter_params(options, params, **)
    options['user'] = User.find_by(id: params[:id])
  end

  def generate_json(options, **)
    # 抽出するカラムを選択
    response = options['user'].slice(:id, :name, :created_at, :updated_at)

    # value を整形
    response[:created_at] = simple_format_time(response[:created_at])
    response[:updated_at] = simple_format_time(response[:updated_at])

    # json を生成
    options['json'] = response.to_json
  end
end
class Users::Operation::Index < ApplicationOperation
  step :generate_json
  failure :handle_generate_json_error!

  private

  def generate_json(options, **)
    # 抽出するカラムを選択
    response = User.all.pluck(:id, :name, :created_at, :updated_at)

    # hash 形式に変更
    keys = %i[id name created_at updated_at]
    response.map! do |response|
      Hash[*[keys, response].transpose.flatten]
    end

    # value を整形
    response.map! do |response|
      response[:created_at] = simple_format_time(response[:created_at])
      response[:updated_at] = simple_format_time(response[:updated_at])
      response
    end

    # json を生成
    options['json'] = response.to_json
  end
end

Controller の実装

 最後に Controller を実装すれば、おしまいですね!
 以下のような app/controllers/api/users_controller.rb を作成しましょう。

class Api::UsersController < ApplicationController
  def show
    result = Users::Operation::Show.call(
      id: params[:id]
    )
    render json: result['json'], status: 200
  end

  def index
    result = Users::Operation::Index.call()
    render json: result['json'], status: 200
  end
end

おわりに

 今回は、 CRUD の R だけをとりあえず実装しようと思ったのですが、色々とやることがありましたね…。次回は、 Rails で Web API 開発(Part. 6 CUD(CRUD) の実装) をおこなっていきます!

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

Rails で Web API 開発(Part. 4 CORS 関連)

はじめに

 本記事は、自身が今までの Ruby on Rails で開発してきた知識 / 知見の総まとめをおこなったものです。
 「ここは、もっとこうしたほうがいいよ!こういうものがあるよ!」というようなことがあれば、随時おしらせください!
 最終的なプロダクトは、 Rails API Sample に置いておきます。

各記事

記事の構成

前回の記事

 前回は、DB の設定を行いました。

今回の記事

 今回は、API を実装するうえで欠かせない CORS の設定をおこなっていきます。

次回の記事

 次回は、実際に CRUD のうちの R の実装をおこなっていきたいと思います。

CORS の設定

Rack Cors

 今回、CORS の設定を行うために、 Rack Cors という gem を扱います。最初の Gemfile に記述済みですので、今回新しくインストールのために何かやる必要はないです。
 さて、おそらくすでに config/initializers/cors.rb というファイルがあるかと思います。このファイルを以下のように編集しましょう。
 $ docker-compose down; docker-compose up を行えば、設定が反映されるはずです。

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    # 全ての origin(Host) からの リクエストを許可する。
    origins '*'
    # /api/ 以下全てのリソースに対して、
    resource '/api/*',
             # 本サーバに対するリクエストにどんな header もつけてもよいとする。
             headers: :any,
             # 本サーバに対するリクエストに以下の method であれば許可をする。
             methods: %i[get, post, put, patch, delete, options, head],
             # 本サーバからのレスポンスの HTTP ヘッダとして公開することを許可する。
             expose:  %i[]
  end
end

おわりに

 ちょっと今回は、はやくなりすぎてしまいました…。次回は、Rails で Web API 開発(Part. 5 R(CRUD) の実装)を行います。

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

Rails で Web API 開発(Part. 3 DB 関連)

はじめに

 本記事は、自身が今までの Ruby on Rails で開発してきた知識 / 知見の総まとめをおこなったものです。
 「ここは、もっとこうしたほうがいいよ!こういうものがあるよ!」というようなことがあれば、随時おしらせください!
 最終的なプロダクトは、 Rails API Sample に置いておきます。

各記事

記事の構成

前回の記事

 前回は、Docker 上で開発をするうえでの下準備を行いました。

今回の記事

 今回は、前回開発した Docker 上で DB の設定を行い、実際に curl コマンド が通るところまで行います。

次回の記事

 次回は、API を実装するうえでかかせない CORS の設定をおこなっていきたいと思います。

ER 図の作成

MySQL Workbench

 ER 図を作成するために、今回は MySQL Workbench を使用します。今回は、使用方法については控えますが(ごにょごにょして)以下のような ER 図を作成しました。(今後、設計図等はリポジトリの docs 配下 に置いておくことにします。)

  • DB 名: rails_api_sample

Screen Shot 2019-02-27 at 15.02.56.png

 また、MySQL Workbench の機能を利用して、以下のような SQL 文を作成しました。

-- MySQL Script generated by MySQL Workbench
-- Wed Feb 27 15:05:04 2019
-- Model: New Model    Version: 1.0
-- MySQL Workbench Forward Engineering

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

-- -----------------------------------------------------
-- Schema rails_api_sample
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema rails_api_sample
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `rails_api_sample` DEFAULT CHARACTER SET utf8 ;
USE `rails_api_sample` ;

-- -----------------------------------------------------
-- Table `rails_api_sample`.`users`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `rails_api_sample`.`users` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(64) NOT NULL,
  `created_at` DATETIME NOT NULL,
  `updated_at` DATETIME NOT NULL,
  PRIMARY KEY (`id`))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `rails_api_sample`.`microposts`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `rails_api_sample`.`microposts` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `content` TEXT NOT NULL,
  `created_at` DATETIME NOT NULL,
  `updated_at` DATETIME NOT NULL,
  `user_id` BIGINT NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `fk_microposts_users_idx` (`user_id` ASC),
  CONSTRAINT `fk_microposts_users`
    FOREIGN KEY (`user_id`)
    REFERENCES `rails_api_sample`.`users` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

テーブルの作成

 実際に、Docker 上の DB に接続しテーブルを作成していきましょう。今回は、 Sequel Pro という MySQL の可視化ツールを用いたいと思います。
 前回の作業をおこなっていれば、以下のような設定で疎通が確認できるはずです。

Screen Shot 2019-02-27 at 16.46.07.png

 先ほど作成した SQL 文を(Sequel Pro 上で)実際に入力することでテーブルが作成できることが確認できます。
 以下は、 SQL 文 入力をし、実行をおこなった後の画面になります。

Screen Shot 2019-02-27 at 16.47.53.png

database.yml の編集

 Docker Compose 上で環境変数を流しているために、以下のような設定を行うことで疎通が行えるはずです。
 記述した後に、再度 $ docker-compose down; docker-compose up を行えば、 $ curl localhost:40000 で疎通確認が行えるはずです。

default: &default
  adapter:  mysql2
  encoding: utf8
  pool:     5
  host:     <%= ENV['MYSQL_HOST'] %>
  username: <%= ENV['MYSQL_USER'] %>
  password: <%= ENV['MYSQL_PASSWORD'] %>
  port:     <%= ENV['MYSQL_PORT'] %>
  database: rails_api_sample

development:
  <<: *default

test:
  <<: *default
  database: rails_api_sample_test

production:
  <<: *default

Migration の管理

 DB というものは、実装をしていくうえでよく変わりうるものです。上記の ER図 を用いて運用上でうまい感じにやっていくというのもできないこともないですが、ちょっと面倒です。
 今回、Migration の管理を行うために、 Ridgepole という gem を扱います。最初の Gemfile に記述済みですので、今回新しくインストールのために何かやる必要はないです。

Ridgepole タスクの作成

 Ridgepole を扱うための Rake タスクを作成してきましょう。今回は、以下のようなファイルを作成します。
 若干コメント文にもありますが 既存の DB から Schemafile を作成することと、またその逆ができるようになります。

# (lib/tasks/ridgepole.rake)

# Schema -> DB
# ./bin/bundle exec rails ridgepole:apply "env"
#
# ex) ./bin/bundle exec rails ridgepole:apply RAILS_ENV=development
#
# DB -> Schema
# ./bin/bundle exec rails ridgepole:export "env"
#
# ex) ./bin/bundle exec rails ridgepole:export RAILS_ENV=development

namespace :ridgepole do
  task export: :environment do
    options = [
      '--export',
      '--split',
      "--output #{schemafile_path}"
    ]
    exec_ridgepole(options)
  end

  task apply: :environment do
    options = [
      '--apply',
      "--file #{schemafile_path}"
    ]
    exec_ridgepole(options)
  end

  def exec_ridgepole(options)
    yml_file_path = Rails.root.join('config', 'database.yml')
    default_options = [
      "--env #{Rails.env}",
      "--config #{yml_file_path}"
    ]
    sh("bundle exec ridgepole #{default_options.join(' ')} #{options.join(' ')}")
  end

  def schemafile_path
    Rails.root.join('db', 'schemas', 'Schemafile')
  end
end

既存の DB から Schemafile を作成 / 更新

 以下のコマンドを実行することで、DB の作成 / 更新を行えるようになっているはずです。作成された Schemafile は、 db/schemas に保存されているはずです。

$ docker-compose run --rm app ./bin/bundle exec rails ridgepole:export RAILS_ENV=development

既存の Schemafile から テーブル を作成 / 更新

 以下のコマンドを実行することで、テーブルの作成 / 更新を行えるようになっているはずです。

$ docker-compose run --rm app ./bin/bundle exec rails ridgepole:apply RAILS_ENV=development

おわりに

 今回は、DB 周りのことに関してお話しました。次回は、Rails で Web API 開発(Part. 4 CORS 関連)を行います。

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

Rails で Web API 開発(Part. 2 Docker 関連)

はじめに

 本記事は、自身が今までの Ruby on Rails で開発してきた知識 / 知見の総まとめをおこなったものです。
 「ここは、もっとこうしたほうがいいよ!こういうものがあるよ!」というようなことがあれば、随時おしらせください!
 最終的なプロダクトは、 Rails API Sample に置いておきます。

各記事

記事の構成

前回の記事

 前回は、Mac 上でとりあえず $ rails server が動くところまでやりました。

今回の記事

 今回は、Docker Container 上で $ rails server が動くようにします。

次回の記事

 次回は、しっかりと DB 部分の実装をおこなっていきます。

各種 Docker ファイルの作成

docker-compose.yaml の作成

 以下のような docker-compose.yaml を作成します。

version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "40050:3306"
    restart: always
    # 環境変数は、Docker 上から流すことにします。
    environment:
      TZ: "Asia/Tokyo"
      MYSQL_ROOT_PASSWORD: rails_api_sample
      MYSQL_DATABASE: rails_api_sample
      MYSQL_USER: rails_api_sample
      MYSQL_PASSWORD: rails_api_sample

  app:
    build: .
    volumes:
      - .:/rails_api_sample
    depends_on:
      - db
    ports:
      - "40000:3000"
    tty: true
    stdin_open: true
    # 環境変数は、Docker 上から流すことにします。
    environment:
      TZ: "Asia/Tokyo"
      MYSQL_HOST: db
      MYSQL_DB: rails_api_sample
      MYSQL_PORT: 3306
      MYSQL_USER: rails_api_sample
      MYSQL_PASSWORD: rails_api_sample

volumes:
  db_data: {}

Dockerfile の作成

 以下のような Dockerfile を作成します。

FROM ruby:2.6.1

RUN mkdir -p /rails_api_sample
WORKDIR /rails_api_sample

RUN apt-get update -qq && \
    apt-get install -y build-essential mysql-client nodejs tzdata

COPY Gemfile* /rails_api_sample/

RUN mkdir -p /rails_api_sample/bin
COPY bin/* /rails_api_sample/bin/

RUN ./bin/bundle install --path vendor/bundle

COPY . /rails_api_sample

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["./bin/bundle", "exec", "rails", "server", "-p", "3000", "-b", "0.0.0.0", "-e", "development"]

Docker 上で rails server

docker-compose up

 以下のコマンドを実行します。

$ docker-compose build

 次に、以下のコマンドを実行します。

$ docker-compose run --rm app ./bin/bundle install --path vendor/bundle

 最後に、以下のコマンドを実行します。

$ docker-compose up

 以下のようになったら、とりあえず完了です!( curl コマンド 等で確認してもおそらく DB 周りの設定ができていないのでちゃんとはかえってこないです…。)

Screen Shot 2019-02-27 at 16.40.12.png

各種コマンド

 覚えておいたほうがよいコマンドに関して少しだけ記述しておきます。

$ docker-compose up : docker-compose を起動します。
$ docker-compose down : docker-compose を停止します。
$ docker-compose run --rm ${SERVICE_NAME} ${COMMAND} : ${SERVICE_NAME} 内で、指定のコマンドを実行します。 ex)$ docker-compose run --rm app bash
$ docker attach ${CONTAINER_NAME} : ${CONTAINER_NAME} 内に、入れます。次の例では、 binding.pry 等を実行する際によく使います。 ex)$ docker attach rails_api_sample_app

おわりに

 まだまだ DB 関連が整っていないです…。次回は、Rails で Web API 開発(Part. 3 DB 関連)を行います。

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

Rails で Web API 開発(Part. 1 概要)

はじめに

 現在、執筆中です。
 本記事は、自身が今までの Ruby on Rails で開発してきた知識 / 知見の総まとめをおこなったものです。
 「ここは、もっとこうしたほうがいいよ!こういうものがあるよ!」というようなことがあれば、随時おしらせください!
 最終的なプロダクトは、 Rails API Sample に置いておきます。

対象

  • Mac での開発者
  • ある程度 Rails / Docker の知識があるとよいかな…。と

各記事

記事の構成

今回の記事

 今回は、全体の記事について記述します。また、とりあえずローカルで $ rails server コマンドが動くところまで記述します。

次回の記事

 Docker を用いた開発を行う上での下準備をおこなっていきます。

主に扱うもの

  • Ruby(ver. 2.6.1) + Ruby on Rails(ver. 5.2.2)
  • Docker + Docker-Compose(コンテナ 関連)
  • MySQL + MySQL Workbench + Sequel Pro + Ridgepole (DB 関連)
  • Rspec + Factory Girl + Shoulda Matcher(テスト 関連)

Rails プロジェクトの作成

Version

 先述のとおり、Ruby / Ruby on Rails の各 Version は、以下の通りです。

Screen Shot 2019-02-27 at 12.31.54.png
Screen Shot 2019-02-27 at 12.35.05.png

rails new

 以下のコマンドを実行しましょう。( DBには、MySQL を使用しAPI モードでMinitest は使わない ようにするオプション。)

$ rails new rails_api_sample --database=mysql --api -T
$ cd rails_api_sample

Gemfile の編集

 今回扱う Gemfile は、以下のようにしています。

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

ruby '2.6.1'

gem 'rails', '5.2.2'

# DB(MySQL) の設定に必要な gem
gem 'mysql2'

# JSON の管理に必要な gem
gem 'jbuilder'

# 'rails server' 起動時に必要な gem
gem 'bootsnap', require: false
gem 'puma'

# CORS の設定に必要な gem
gem 'rack-cors'

# Migration の管理に必要な gem
gem 'ridgepole'

# Trailblazer を扱うのに必要な gem
gem 'reform-rails'
gem 'trailblazer-loader'
gem 'trailblazer-rails'

group :development, :test do
  # 便利コマンド 'binding.pry' を使用するのに必要な gem
  gem 'pry-byebug'
  gem 'pry-doc'
  gem 'pry-rails'

  # ソースコードが綺麗かどうか Check する gem
  gem 'rubocop'
end

group :development do
  # ファイルの変更を監視する gem
  gem 'listen'

  # 起動を早くするために必要な gem
  gem 'spring'
  gem 'spring-watcher-listen'
end

group :test do
  # TEST 用 DB の管理をする gem
  gem 'database_rewinder'

  # TEST 用 データの管理をする gem
  gem 'factory_bot_rails'
  gem 'faker'

  # Rspec で TEST をするために必要な gem
  gem 'rspec-json_matcher'
  gem 'rspec-rails'
  gem 'rspec_junit_formatter'

  # モデルの関連を TEST するために必要な gem
  gem 'shoulda-matchers'
end

bundle install

 以下のコマンドを実行しましょう。( vendor/bundle 配下にインストール するオプション。)

$ bundle install --path vendor/bundle

rails server

 以下のコマンドを実行しましょう。( $ rails s$ rails server の省略コマンド。 -p はポート指定。-b はIP Address指定。-e は環境指定。

$ bundle exec rails s -p 3000 -b '127.0.0.1' -e 'development'

 以下のようになったら、とりあえず完了です!( curl コマンド 等で確認してもおそらく DB 周りの設定ができていないのでちゃんとはかえってこないです…。)

Screen Shot 2019-02-27 at 14.36.50.png

おわりに

 今回は、とりあえず $ rails server コマンドまでを行いました。次回は、Rails で Web API 開発(Part. 2 Docker 関連)を行います。

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

RailsのMVCってなに?

フレームワークの構造についてメモ。

Railsに限らず他のフレームワークも、MVCの構造になっています。
この仕組を少し理解してからのほうが、一連の流れを理解しやすいかと思います。

M:Model
V:View
C:Controller


  • M データベースからデータを引っ張ってきます。
  • V pe+tab で <%= >が補完。これを使うことでHTMLをブラウザに表示させることが出来ます。
    つまり ERB {enbedded(埋め込み) Ruby} 出来ます。ファイル拡張子も .erb になってることが多いですが、ERBと繋がりますね!
  • C 管制!というイメージです。MとVに指示を出します。

下記サイトがとても噛み砕いて説明してあり分かりやすかったです。
(参考https://www.yuta-u.com/programing/rails_mvc)

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

Railsでaccets_nested_attributes_forを使わずに複数子レコードを同時保存

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

bundle installのmysql2 のエラー解決方法

【環境】
macOS Mojava
バージョン10.14.3

・ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin18]

・rbenv versions
system
2.2.2
2.3.0
2.3.1
* 2.3.3 (set by /Users/ユーザー名/サイト名/.ruby-version)
2.4.1
2.5.3

mysql --version

/usr/local/opt/mysql@5.7/bin/mysql Ver 14.14 Distrib 5.7.25, for osx10.14 (x86_64) using EditLine wrapper

vi ~/.bash_profile

PATH=/usr/local/mysql/bin:$PATH
export PATH
export PATH="~/.rbenv/shims:/usr/local/bin:$PATH"

eval "$(rbenv init -)"

vi ~/.bashrc

alias mysql=/usr/local/opt/mysql@5.7/bin/mysql

alias mysqladmin=/usr/local/opt/mysql@5.7/bin/mysqladmin

【エラー内容】

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

Gem files will remain installed in
/Users/ユーザー名/サイト名/vendor/bundle/ruby/2.3.0/gems/mysql2-0.4.5 for
inspection.
Results logged to
/Users/ユーザー名/サイト名/vendor/bundle/ruby/2.3.0/extensions/x86_64-darwin-18/2.3.0-static/mysql2-0.4.5/gem_make.out

An error occurred while installing mysql2 (0.4.5), and Bundler cannot
continue.
Make sure that gem install mysql2 -v '0.4.5' --source 'https://rubygems.org/'
succeeds before bundling.

In Gemfile:
mysql2



【試した事】

・パスを通す
https://nekonenene.hatenablog.com/entry/2016/10/31/061350
の解決方法①

bundle config build.mysql2 --with-opt-lib=/usr/local/opt/openssl/lib --with-opt-include=-I/usr/local/opt/openssl/include

・インストール実行
gem install mysql2 -v '0.4.5' --source 'https://rubygems.org/'

▼エラー内容
ERROR: Error installing mysql2:
ERROR: Failed to build gem native extension.


・gemfileのtherubyracerをコメントアウト

gem 'therubyracer'


・Xcodeの再インストール
xcode-select --install

▼エラー内容(インストール済)

xcode-select: error: command line tools are already installed, use "Software Update" to install updates

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

リポジトリのURLって?

Gitにpushしたリポジトリを他の人へ共有したい時。
リポジトリのURLを送って!と言われますね(^^)

リポジトリのURLはどこで分かるのだろう??とGitをポチポチしていて
分かったのでメモです。

まずは
Gitの自分のリポジトリ(your repositories)画面に移動します。
URLを知りたいリポジトリを選んでください。リポジトリをクリックすると、
スクリーンショット 2019-02-28 14.32.05.png

「Clone or download」という緑のボタンが画面右の方に有るので
そのボタンをクリックしてください。


クリックするとなにかアドレスが出てきますが、今回はHTTPSの方のURLが欲しいので
Use HTTPSをクリックすると、
いつものhttpsから始まる見慣れたURLが出てきます(^o^)ホッ
URL右横のコピーボタンを押せばコピーできます。

スクリーンショット 2019-02-28 14.41.43.png

スクリーンショット 2019-02-28 14.58.52.png



その後、困ったことがありました汗
今回の操作により、gitにpushする時の使用が変わってしまっていたようで、push時にパスワード聞かれるようになってしまいました。
HTTPSに変更した方は、SSHに戻しましょう。

(参考https://qiita.com/rorensu2236/items/df7d4c2cf621eeddd468)

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

Ruby if文,case文

動作環境はMacとなります。

if文

条件によって処理を出し分けたいときに使う

記述方法

if 条件1
条件 1が真(true)だった場合の処理
elsif 条件2
条件2が真(true)だった場合の処理
elsif 条件3
条件3が真(true)だった場合の処理
else
上記のいずれにも当てはまらなかった場合の処理
end

条件が真になったタイミングで処理を抜ける。
後の処理は実行されない。

※elsifの綴りはelseifではないため、注意


実践1

テストの点数が
90点以上 大変よくできました
80点以上 よくできました
60点以上 普通です
60点未満 頑張りましょう

と出力されるプログラムを実際に書いてみる

if.rb
score = x(任意の数字を入れる)

if score >= 90
  puts "大変よくできました"
elsif score >= 80
  puts "よくできました"
elsif score >= 60
  puts "普通です"
else
  puts "頑張りましょう"
end

処理結果

$ruby if.rb
普通です  #score60点以上
$ruby if.rb
頑張りましょう   #score60点未満(59点以下)
$ruby if.rb
大変よくできました  #score90点以上
$ruby if.rb
よくできました  #score80点以上
kouya:ruby_proje

#条件が真(true)になった段階でif文を抜けている。
#また、59点以下の場合はelse内の処理が実行されている。

実践2

catならmeow
dogならbowwow
cowならmoomoo
上記以外ならNot found

と出力されるプログラム

if2.rb
animal = X(任意の変数が入る)

if animal == "cat"
  puts "meow"
elsif animal == "dog"
  puts "bowwow"
elsif animal == "cow"
  puts "moomoo"
else
  puts "Not found"
end

# =は右辺を左辺に代入するとき ==は右辺と左辺が等しいときに使用するので注意

出力結果


$ ruby if2.rb
meow #animalがcat
$ ruby if2.rb
bowwow #animalがdog
$ ruby if2.rb
moomoo #animalがcow
$ ruby if2.rb
Not found " #animalが上記以外

実践3

遊園地の入場料のプログラム
12歳以上 入場料 5,000円
6歳以上12歳未満 入場料 2,500円
6歳未満 1,000円

if3.rb
age = x(任意の値が入る)

if age >= 12
  puts 5000
elsif age >= 6
  puts 2500
else age < 6
  puts 1000
end

出力結果

kouya:ruby_projects toripurug884$ ruby if3.rb
1000 #6歳未満
kouya:ruby_projects toripurug884$ ruby if3.rb
5000 #12歳以上
kouya:ruby_projects toripurug884$ ruby if3.rb
2500 #6歳未満12歳以上

unless文

記述方法

unless 条件
条件が偽(false)だった場合の処理
else
上記に当てはまらなかった場合の処理
end

※unlessにelsifは書かない。

条件が偽になったタイミングで処理を抜ける。
後の処理は実行されない。


nが0で無かった場合、出力するプログラムを書く

if文の場合

unless.rb
n = 1

if !n.zero?
  puts "Not zero"
end


unless文の場合

unless.rb
n = 1
unless n.zero?
  puts "This is zero"
end

$ ruby unless.rb
Not zero
Not zero

0の場合に出力するプログラムを unless文で追加

unless.rb
n = 0

unless n.zero?
  puts "Not zero"
else
  puts "This is zero"
end

出力結果

unless.rb
$ ruby unless.rb
This is zero

unlessは無理に使う必要はなく、ifでも読み易ければOK

case文

記述方法

case 対象のオブジェクトや式
when
値1に一致する場合の処理
when
値2に一致する場合の処理
when
値3に一致する場合の処理
else
上記のいずれにも該当しない場合
end


実践

下記のプログラムを実装

誕生石がrubyだった場合 July
誕生石がperidotだった場合 August
誕生石がsapphireだった場合 September
上記意外だった場合 Not found

ifで書いた場合

case.rb
stone =  x(任意の値を代入)

if stone == "ruby"
  puts "July"
elsif stone == "peridot"
  puts "August"
elsif stone == "sapphire"
  puts "September"
else
  puts "Not Found"
end

case.rb
$ ruby case.rb
July #ruby
$ ruby case.rb
August #peridot
$ ruby case.rb
September #sappire
$ ruby case.rb
Not Found #上記以外

case文で書いた場合

case.rb
stone = x (任意の値が入る)

case stone
when "ruby"
  puts "July"
when "peridot"
  puts "August"
when "sapphire"
  puts "September"
else
  puts "Not found"
end

出力結果

$ ruby case.rb
July #ruby
$ ruby case.rb
August #peridot
$ ruby case.rb
September #sapphire
$ ruby case.rb
Not found #上記以外

if文で書くより、caseで書いた方がシンプルでわかりやすいことがある。
特に、複数の条件に分岐する場合はcaseの方が見やすい場合が多い。

まとめ

複数人で開発場合、特ににコードの見易さやメンテナンス性が重要視される
自分にしかわからないコードを書くのではなく、相手にわかりやすいコードを書くように心がける必要がある。

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

resourceとresourcesでは作られるroutesが違ってハマった

はじめに

UdemyでRuby on Rails入門中です。自分のコーディングミスで小一時間ほどハマったので簡単にまとめておきます。

The Complete Ruby on Rails Developer Course
https://www.udemy.com/the-complete-ruby-on-rails-developer-course/

環境

  • AWS Cloud9
  • ruby 2.6.0p0
  • Rails 5.0.7.1

resourceの場合

config/routes.rb
Rails.application.routes.draw do
  resource :articles
end

routesは以下のようになります。:idパラメータが含まれず、想定と異なるルーティングとなりました。所々エラーも出てハマりました。

$ rails routes
       Prefix Verb   URI Pattern              Controller#Action
         root GET    /                        pages#home
        about GET    /about(.:format)         pages#about
 new_articles GET    /articles/new(.:format)  articles#new
edit_articles GET    /articles/edit(.:format) articles#edit
     articles GET    /articles(.:format)      articles#show
              PATCH  /articles(.:format)      articles#update
              PUT    /articles(.:format)      articles#update
              DELETE /articles(.:format)      articles#destroy
              POST   /articles(.:format)      articles#create

resourcesの場合

config/routes.rb
Rails.application.routes.draw do
  resources :articles
end

想定通り:idパラメータが含まれるroutesが作成されました。

$ rails routes
      Prefix Verb   URI Pattern                  Controller#Action
        root GET    /                            pages#home
       about GET    /about(.:format)             pages#about
    articles GET    /articles(.:format)          articles#index
             POST   /articles(.:format)          articles#create
 new_article GET    /articles/new(.:format)      articles#new
edit_article GET    /articles/:id/edit(.:format) articles#edit
     article GET    /articles/:id(.:format)      articles#show
             PATCH  /articles/:id(.:format)      articles#update
             PUT    /articles/:id(.:format)      articles#update
             DELETE /articles/:id(.:format)      articles#destroy

参考

【初心者】routes.rbをもうちょっと深く理解する

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

Ruby 演算子,真偽値

動作環境はMacとなります。

比較演算子

演算子による値の比較
2つの値の大小と同じ値かを調べる方法

比較演算子の記号
※マークダウン方式の影響で、より大きいの記述がおかしくなってます。

より大きい > ⇦これ
= 以上
< より小さい
<= 以下
== 等しい
!= 等しくない


式が成り立つ場合 true
式が成り立たない場合falseを返す


irb#1(main):001:0> 1 < 2
=> true
irb#1(main):002:0> 1 <= 2
=> true
irb#1(main):003:0> 1 > 2
=> false
irb#1(main):004:0> 1 >= 2
=> false
irb#1(main):005:0> 1 == 2
=> false
irb#1(main):006:0> 1 != 2
=> true

演算子の優先順位

irb#1(main):007:0> 1.0 + 2.0 * 3.0 / 4.0 
=> 2.5
irb#1(main):008:0> (1.0 + 2.0) * 3.0 / 4.0 #()で優先順位を上げる
=> 2.25

高い ::
[]
+(単項) ! ~
**
-(単項)
* / %
+ -
<< >>
&
| ^
> >= < <=
<=> == === != =~ !~
&&
||
.. ...
?:(条件演算子)
=(+=, -= ... )
not
低い and or


数値と文字列は暗黙的に変換されない

数値と文字列を連結するとエラー

irb#1(main):009:0> 1 + "1"
TypeError: String can't be coerced into Integer
    from (irb#1):9:in `+'
    from (irb#1):9

文字列を数値に変換

irb#1(main):011:0> 1 + "1".to_i #整数クラスに変換
=> 2
irb#1(main):012:0> 1 + "1.1".to_f #浮動小数点クラスに変換
=> 2.1

出力された!


数値を文字列に変換

irb#1(main):015:0> num = 10
=> 10

irb#1(main):021:0> "Number name is " + num
TypeError: no implicit conversion of Integer into String
    from (irb#1):21:in `+'
    from (irb#1):21
#numが変数のため、わかりにくいが文字列と数値の足し算はエラー

irb#1(main):020:0> "Number name is " + num.to_s
=> "Number name is 10"

#数値を文字列に変換

出力された!


インクリメントとディクリメント

・インクリメント
数値に1を足す

・ディクリメント
数値から1を引く

他のプログラミング言語のように++や--で表すことができない点に注意!

irb#1(main):022:0> n = 1
=> 1
irb#1(main):023:0> n = n + 1
=> 2
irb#1(main):024:0> n += 1
=> 3
irb#1(main):025:0> n = n -  1
=> 2
irb#1(main):026:0> n -= 1
=> 1

#どちらの表記でも大丈夫だが、+=や-=で表した方がスマート

真偽値

Rubyでは、nilかfalseの場合は偽(false)
それ以外は真(true)

trueの例

  • trueそのもの・・・true
  • 全ての数値・・・1,1.5,2/3
  • 全ての文字列 ・・・"false","true",""(空文字)

論理演算子

&&や||で複数の条件の式を真偽値で返すことが可能になる。

論理積
&&(かつ)=全ての条件が真の場合trueを返す

論理和
||(または)=少なくとも一つの条件が当てはまれば真になり、trueを返す

and,or,not

&&,||,!とほぼ同じ役割
ただし計算の優先順位が異なるため、式に混在させないこと


irb(main):001:0> t1 = true
=> true
irb(main):002:0> t2 = true
=> true
irb(main):003:0> f1 = false
=> false
irb(main):004:0> f2 = false
=> false
irb(main):005:0> t1 and t2
=> true
irb(main):006:0> t1 and f1
=> false
irb(main):007:0> t1 or t2
=> true
irb(main):008:0> f1 or f2
=> false
irb(main):009:0> !t1 || t1 #trueとfalse
=> true

#混在させると非常にわかりにくくなるため注意
irb(main):010:0> not t1 || t1
=> false
irb(main):011:0> t1 || t2 && f1 #&&の方が優先順位が高いため、t2とf1の計算が先にされた後、t1との和が計算される。
=> true
irb(main):012:0> t1 or t2 and f1 #orとandの優先順位は等しいので、左から計算
=> false

#()で囲ったりわかりやすくすることは複数人で開発するときには欠かせないスキル
irb(main):013:0> (t1 || t2) && f1 
=> false

まとめ

リファレンスに書いてある優先順位が高いものと低いものを混在させると非常にわかりにくい。
また、優先順位を上げたいときは()でくくるなど、直感的でわかりやすいプログラムを書くことが重要。

シンプルに記述するように心がけよう!

参考文献

Ruby 2.6.0 リファレンスマニュアル 演算子式

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

Ruby オブジェクト指向、数値、文字列

動作環境はMacとなります。
主に自分の勉強用メモとして残しています。

オブジェクト指向プログラミング言語

  • コンピュータ・プログラミングの概念の一つ。
  • オブジェクト指向の概念や手法を取り入れたもの。
  • プログラムを、データとその振る舞いが結びつけられたオブジェクトの集まりとして構成する。

オブジェクトとは?
データと処理の集まりのこと。文字列、配列、数値、nilなど全てオブジェクト。

オブジェクト指向とは?
オブジェクト同士が相互に関係しあうことで、システムの振る舞いを捉える考え方。

クラス
オブジェクトの設計図

インスタンス
クラス(設計図)から作成した、実態。

メソッド

  • クラスの中に定義されていて、複数の処理を1つにまとめて、扱いやすくしたもの
  • クラスに所属する関数のようなもの

数値(Numeric)

Numericは親クラス

  • Numeric ・・・ 数値クラス 
    • Integer ・・・ 整数クラス(整数を扱うクラス)
    • Float ・・・浮動小数点クラス(小数点以下を扱うクラス)

動的型付け

変数に格納した時に自動的に型が設定されるため、明示的にクラスを書く必要はない。

例) 
i = 1はOK
int i = 0はNG


四則演算 

irb(main):045:0> 1 + 1
=> 2
irb(main):046:0> 10 - 1
=> 9
irb(main):047:0> 13 * 2 #掛け算
=> 26
irb(main):048:0> 100 / 5 #割り算
=> 20
irb(main):049:0> x = 1 #xに1を代入
=> 1
irb(main):050:0> - x #入れた変数に-をつけると符号を反転させることができる
=> -1

割り算の注意点


irb(main):053:0* 3 / 2 #小数点の計算がされない
=> 1

#どちらかまたはどちらの数値にも小数点をつける必要がある
irb(main):054:0> 3.0 / 2
=> 1.5
irb(main):055:0> 3 / 2.0
=> 1.5
irb(main):056:0> 3.0 / 2.0
=> 1.5
irb(main):001:0> 10 % 3 #剰余
=> 1
irb(main):002:0> 10 ** 3 #べき乗
=> 1000

irb(main):004:0> x = 5 #5を代入
=> 5
irb(main):005:0> x.to_f #小数に変換
=> 5.0
irb(main):006:0> x.to_f / 7 #5を小数に変換し、7で割る
=> 0.7142857142857143
irb(main):007:0> x / 7   #5 / 7の出力結果 ※小数点は出力されない
=> 0

#クラスの確認
irb(main):008:0> 1.class
=> Integer
irb(main):009:0> 1.1.class 
=> Float

#クラスのメソッドの確認
irb(main):010:0> 1.methods
=> [:%, :&, :*, :+, :-, :/, :<, :>, :^, :|, :~, :-@, :**, :<=>, :<<, :>>, :<=, :>=, :==, :===, :[], :inspect, :size, :succ, :to_int, :to_s, :to_i, :to_f, :next, :div, :upto, :chr, :ord, :coerce, :divmod, :fdiv, :modulo, :remainder, :abs, :magnitude, :integer?, :floor, :ceil, :round, :truncate, :odd?, :even?, :downto, :times, :pred, :bit_length, :digits, :to_r, :numerator, :denominator, :rationalize, :gcd, :lcm, :gcdlcm, :+@, :eql?, :singleton_method_added, :i, :real?, :zero?, :nonzero?, :finite?, :infinite?, :step, :positive?, :negative?, :quo, :arg, :rectangular, :rect, :polar, :real, :imaginary, :imag, :abs2, :angle, :phase, :conjugate, :conj, :to_c, :between?, :clamp, :instance_of?, :kind_of?, :is_a?, :tap, :public_send, :public_method, :singleton_method, :remove_instance_variable, :define_singleton_method, :method, :instance_variable_set, :extend, :to_enum, :enum_for, :=~, :!~, :respond_to?, :freeze, :object_id, :send, :display, :nil?, :hash, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variable_get, :instance_variables, :instance_variable_defined?, :!, :!=, :__send__, :equal?, :instance_eval, :instance_exec, :__id__]

文字列(String)

文字列はシングルクオートかダブルクオートで囲む。

挙動の違い


irb(main):006:0> "abcde"
=> "abcde"
irb(main):007:0> 'abcde'
=> "abcde"

#この時点での違いはない。



irb(main):001:0> puts "Ruby\nProgramming"
Ruby
Programming
=> nil
irb(main):002:0> puts 'Ruby\nProgramming'
Ruby\nProgramming
=> nil

#ダブルクオートで囲むと、文字列の途中で改行される
#シングルクオートで囲むと、改行されない

※バックスラッシュはoptionキー+¥キー

irb(main):003:0> first_name = "Yuta"
=> "Yuta"
irb(main):004:0> last_name = "Nakamura"
=> "Nakamura"
irb(main):006:0> "My name is #{first_name} #{last_name}"
=> "My name is Yuta Nakamura"
irb(main):007:0> 'My name is #{first_name} #{last_name}'
=> "My name is \#{first_name} \#{last_name}"

#ダブクオートで囲むと#{}で囲んだ文字列が式展開される
#シングルクオートではそのまま表示される

まとめ
ダブルクオートを使う場合・・・式展開、改行したい時
シングルクオートを使う場合・・・それ以外


その他文字列の使い方

irb(main):010:0> puts "kengo" + "kaneki"
kengokaneki
=> nil
irb(main):011:0> puts "kengo" + " " + "kaneki"
kengo kaneki

#スペースを開けたい場合、" "を連結

破壊的メソッド  メソッド名の最後に!を記述

irb(main):017:0> name = 'ken'
=> "ken"
irb(main):018:0> puts name
ken
=> nil

#upcaseメソッドの破壊的メソッド
irb(main):019:0> name.upcase
=> "KEN"
irb(main):020:0> name
=> "ken"
#変数の中身に変化はない


irb(main):021:0> name.upcase!
=> "KEN"
irb(main):022:0> name
=> "KEN"
#変数の中身自体が大文字に書き換わる

クラスの確認

irb(main):023:0> "ken".class
=> String

メソッドの確認


irb(main):024:0> "ken".methods
=> [:include?, :%, :*, :+, :to_c, :unicode_normalize, :unicode_normalize!, :unicode_normalized?, :count, :partition, :unpack, :unpack1, :sum, :next, :casecmp, :casecmp?, :insert, :bytesize, :match, :match?, :succ!, :+@, :-@, :index, :rindex, :<=>, :replace, :clear, :upto, :getbyte, :==, :===, :setbyte, :=~, :scrub, :[], :[]=, :chr, :scrub!, :dump, :byteslice, :upcase, :next!, :empty?, :eql?, :downcase, :capitalize, :swapcase, :upcase!, :downcase!, :capitalize!, :swapcase!, :hex, :oct, :split, :lines, :reverse, :chars, :codepoints, :prepend, :bytes, :concat, :<<, :freeze, :inspect, :intern, :end_with?, :crypt, :ljust, :reverse!, :chop, :scan, :gsub, :ord, :start_with?, :length, :size, :rstrip, :succ, :center, :sub, :chomp!, :sub!, :chomp, :rjust, :lstrip!, :gsub!, :chop!, :strip, :to_str, :to_sym, :rstrip!, :tr, :tr_s, :delete, :to_s, :to_i, :tr_s!, :delete!, :squeeze!, :each_line, :squeeze, :strip!, :each_codepoint, :lstrip, :slice!, :rpartition, :each_byte, :each_char, :to_f, :slice, :ascii_only?, :encoding, :force_encoding, :b, :valid_encoding?, :tr!, :encode, :encode!, :hash, :to_r, :<, :>, :<=, :>=, :between?, :clamp, :instance_of?, :kind_of?, :is_a?, :tap, :public_send, :public_method, :singleton_method, :remove_instance_variable, :define_singleton_method, :method, :instance_variable_set, :extend, :to_enum, :enum_for, :!~, :respond_to?, :object_id, :send, :display, :nil?, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variable_get, :instance_variables, :instance_variable_defined?, :!, :!=, :__send__, :

空白文字の使い方

irb(main):025:0> 1 + 2
=> 3
irb(main):026:0> 1+2 
=> 3
irb(main):027:0> 1                  +2             +    3
=> 6

#スペースはいくら開けても開けなくても挙動に違いはない。
基本的にはスペースを一文字ずつ空けるのが定説
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む