20200211のRailsに関する記事は25件です。

[Ruby on Rails] includesメソッドの書き方まとめ

実務でまさかのincludesメソッドに戸惑う

「この画面の情報をスプレッドシートに出力しておいて」

「はーい」
(データを取ってくるだけなら余裕だろ、、、)

(あれ、関連するモデル多すぎじゃね?)

(関連するモデルに関連するモデルも取得、、あれ、、頭が、、、)

って感じで整理できていない部分がありましたので、今回まとめておきます。

前提

  • モデルの関連付けだけをテーマに書きます。
  • includesする際、単数形か複数形かはアソシエーションによって判断します。
  • N+1問題を解決するためにincludesします。( 参考記事 )

今回例示するモデル

  • Tweets:ツイート
  • Users:ユーザー
  • Comments:ツイートに対するコメント
  • Tags:ツイートにつけるタグ
  • Addresses:ユーザーの住む住所

ここでは便宜上、関連するモデルを子モデル、子モデルに関連するモデルを孫モデルと呼ぶことにします。

① 子モデルが1つの場合

Tweet.includes(:user)

こちらはTweetに紐づくUser(子)を取得します。

② 子モデルが2つの場合

Tweet.includes(:user, :tags)

こちらはTweetに紐づくUser(子)およびTag(子)を取得します。 ([:user, :tags]) と書く場合もあるので、それは所属するチームでの決まりに従うと良いでしょう。

③ 子モデル・孫モデルが1セットの場合

Tweet.includes(user: :address)

:(コロン)の位置に注意です。こちらはTweetに紐づくUser(子)とそのUserに紐づくAddress(孫)を取得します。

孫モデルが複数ある場合

Tweet.includes(user: [:address, :comments])

明示的に[]が必要です。こちらはTweetに紐づくUser(子)とそのUserに紐づくAddress(孫)およびComment(孫)を取得します。

③ 子モデル・孫モデルが1セットと子モデルが1つの場合

Tweet.includes(:tags, user: :address)

注意すべき点は、孫モデルまで参照するものを後ろに記述することです。こちらはTweetに紐づくTag(子)およびUser(子)とそのUserに紐づくAddress(孫)を取得します。

Tweet.includes(user: :address, :tags)とすると、筆者の場合 SyntaxError: unexpected ')', expecting => と表示されてしまいます。
※ もし子モデル・孫モデルのセットが増えたなら、後ろに加えれば大丈夫です。

【募集】 STIをincludesする場合

今現在まだ実務で出会っていませんが、STIを参照する際のincludesの形はどうなるのだろう、、と今から不安です。もし、参考記事などございましたらご教授いただければ幸いです。

これからも新しい書き方を見つけたら更新していきます

実務未経験から働き始めて約1週間。まだまだこんなものではないと思いますので、気付き次第随時更新していきます。

参考記事

Rails ActiveRecord/SQL 小技集

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

Rails6 DBにsaveする時にROLLBACKしてしまい原因がわからない時

目的

  • DBにsaveする際にROLLBACKしているときのエラーの表示方法をまとめる

実施方法

  • saveの命令の後ろに!をつけてあげるとエラー文が表示される。

具体的な例

  • @user.saveをただ実行しただけの時

    User Exists? (0.5ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = 
    BINARY 'miriwo.rails@gmail.com' LIMIT 1
    (0.2ms)  ROLLBACK
    => false
    
  • @user.save!を実行した時

    User Exists? (0.5ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = 
    BINARY 'miriwo.rails@gmail.com' LIMIT 1
    (0.2ms)  ROLLBACK
    Traceback (most recent call last):
        1: from (irb):21
    ActiveRecord::RecordInvalid (Validation failed: Password can't be blank)
    
  • 最後にエラー文が一文追加されたことがわかる

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

Windowsでrailsの環境構築。yarnとgulp編

yarnでRailsの環境構築

Railsの環構築の時にサラッと出来るように自分用に投稿。
完璧に初心者なのであしからず

※ちなみにyarnもgulpもnodeもインストール済みとして書きます。

環境

・yarn
1.21.1
・gulp
CLI version: 2.2.0
Local version: 4.0.2 `
・node(楽だからnodistで管理したほうがいいかも)
v11.13.0

手順

test(任意)フォルダの中に移動します

 C:\Users\(ユーザー名) > CD test
 C:\Users\(ユーザー名)\test >

ちなみにtestフォルダの中は下記になります

 test─┬─css
      ├─scss
      │  └─main.scss
      └─index.html

package.jsonを生成しないとダメなので下記を実行

 C:\Users\(ユーザー名)\test > yarn init

実行すると色々聞かれるけどエンター連打。
そうするとtest直下にpackage.jsonが生成される。

 test─┬─css
      ├─scss
      │  └─main.scss
      ├─package.json
      └─index.html

パッケージをインストールします。なのでとりあえず下記を実行。
(後で色々変更できるけどとりあえず)

 C:\Users\(ユーザー名)\test > yarn add --dev gulp
 C:\Users\(ユーザー名)\test > yarn add --dev gulp-sass
 C:\Users\(ユーザー名)\test > yarn add --dev gulp-autoprefixer
 C:\Users\(ユーザー名)\test > yarn add --dev gulp-plumber

次にgulpfile.jsの生成。これは自分で作らないとだめなやーつ。
作ったらtestフォルダに放り投げといて下さい。
中身はざっくりこんな感じ。

const { watch, series, task, src, dest } = require('gulp');
const sass                               = require('gulp-sass');
const autoprefixer                       = require('gulp-autoprefixer');
const plumber                            = require('gulp-plumber');

const convertToCss = () =>
    src('scss/*.scss')
      .pipe(plumber())
      .pipe(sass())
      .pipe(autoprefixer())
      .pipe(dest('css/'));

const watchscss = () =>
    watch('scss/*.scss', convertToCss);

exports.default = watchscss;

.pipe(dest('css/'));の部分を
.pipe(dest('css'));にしててそれに気づかず大変でした。

最後に下記を実行して終了

 C:\Users\(ユーザー名)\test > yarn gulp

これでちゃんとコンパイルが出来ているはず。
何故かこれだけの作業なのに結構時間がかかった。

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

【rails】credentials.yml.encについて

はじめに

初学者がポートフォリオ作成でハマったことをメモします。
AWSにデプロイする際credentials.yml.encでハマったので箇条書きでメモしておきます。

credentials.yml.encについて

・秘密情報を保持するためのファイル。
・configディレクトリに作成される。
・rails newで作られる。
・暗号化されておりgithubで管理出来る。
・復号化する為には同じくrails newで作成されるconfig/master.keyを使う。
・master.keyを削除してしまった場合はcredentials.yml.envを削除した後sudo EDITOR=vim rails credentials:editで新しいcredentials.yml.envとmaster.keyを作成する。
・リポジトリーをcloneした場合master.keyはコピーされていない為、master.keyをコピぺする必要がある。
・直接エディタから編集する事ができない。vimを使って編集可能。 $ EDITOR=vim bin/rails credentials:edit
・デフォルトでコメントアウトがついている為注意。
・master.keyが共有できない環境では環境変数:RAILS_MASTER_KEYを指定する。

参考にした記事

https://qiita.com/yamamoto_shuji/items/5afd9ffe13f36ff29677
https://qiita.com/scivola/items/cc06ddbfd94d3118f693

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

rails内の環境構築 その2

scaffoldでサンプルアプリを作る

docker-compose run web rails g scaffold  user name:string address:string age:integer

そして

docker-compose run web rails db:migrate

ブラウザでlocalhost:3000/usersでアクセスできますが、毎回めんどいのでrootに指定します

confing/routes.rb
Rails.application.routes.draw do
  resources :users
  root 'users#index'
end

slimを導入

gem 'slim-rails'
gem 'html2slim'

そして

docker-compose run web bundle install

さらに

docker-compose build

既存のerbファイルをslim可する

docker-compose run web bundle exec erb2slim app/views/layouts/ --delete
docker-compose run web bundle exec erb2slim app/views/users/ --delete

rspec導入

group :development, :test do
  gem 'rspec-rails'
  gem 'factory_bot_rails'
end

そして

docker-compose run web bundle install
docker-compose build

さらに

docker-compose run web rails g rspec:install
rm -r ./test

rspec使い方

docker-compose run web rspec

System Spec導入

Dockerfileに書き込む

  • dockerコンテナの中へ新たにchromedriverを準備なければなりません。
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

# chromeの追加
RUN apt-get update && apt-get install -y unzip && \
    CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` && \
    wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/ && \
    unzip ~/chromedriver_linux64.zip -d ~/ && \
    rm ~/chromedriver_linux64.zip && \
    chown root:root ~/chromedriver && \
    chmod 755 ~/chromedriver && \
    mv ~/chromedriver /usr/bin/chromedriver && \
    sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' && \
    sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \
    apt-get update && apt-get install -y google-chrome-stable


RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# 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

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

ディレクトリ作成

mkdir spec/system
mkdir spec/support
touch spec/support/capybara.rb

設定を書く

spec/support/capybara.rb
require 'capybara/rspec'
require 'selenium-webdriver'

Capybara.register_driver :selenium_chrome_headless do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new


  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-dev-shm-usage')
  options.add_argument('--window-size=1400,1400')


  driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

Capybara.javascript_driver = :selenium_chrome_headless
spec/rails_helper.rb
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
#↑コメントアウトする これによりspec/support/capybara.rbが読み込まれます。

RSpec.configure do |config|
  config.before(:each) do |example|
    if example.metadata[:type] == :system
      if example.metadata[:js]
        driven_by :selenium_chrome_headless, screen_size: [1400, 1400]
      else
        driven_by :rack_test
      end
    end
  end
end
#type: :systemのときのみchromeを使うという設定です。

テストの実行

docker-compose run web rspec spec

参考

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

Railsで個別にCSSを適用させる方法

結論

config/initializers/assets.rbに
'Rails.application.config.assets.precompile += %w( user.css )'
を追加することで解決した。
いろいろ調べてもわからなかったが、エラーが出たときの指示に従ったら解決したので、赤い文字がたくさん出てきても焦らずに対処すれば問題ないということがわかった。

背景

htmlやcssの勉強は対してしていなかったものあり、デザインをいじることに抵抗があった。
そんなとき、Bootstrapが便利だと職場のエンジニアの方々からきき、デザインに全く手が回っていないサービスにBootstrapの実装を試みた。

Bootstrapをいろいろ探していると無料のテーマというのがあることを知った。
元々ワードプレスでブログを書いていたことがあったので、ワードプレスのテーマと非常に似ているなと感じた。

Bootstrapのテーマを探すとサイト丸ごとをデザインできるようなものもあったが、Bootstrapについてよくわからないし、せっかく実装したslickを使ったJQueryの動きに影響が出ても嫌なので、作ってすらいなかったログインページをまず作り、そのページにだけBootstrapのデザインを反映させようとした。

苦悩

htmlのページにcssを読み込む方法は知っていたつもりだったが、user.scssというscssファイルの読み込みがどうしてもできずにいた。
同じcssのコードをapplication.scssに貼り付けるとサイト全体に反映されてしまうが、これだとちゃんとログイン画面もお洒落なデザインになっていた。
どうにかしてログイン画面にのみデザインを反映させたいと思い、いろいろ調べてみたが、compileがどうとか、
= require_tree . と= require_selfの順番がどうとかがたくさん出てきて、困った。
諦めてteratailで質問をするためにどのようなエラーが出ているのかを確認しようと、htmlに読み込みのためのコードを書き、ブラウザで確認した。
すると
「Asset was not declared to be precompiled in production.
Add Rails.application.config.assets.precompile += %w( user.css ) to config/initializers/assets.rb and restart your server」と丁寧に書いてあり、
言われた通りに丸々コピーしてassets.rbに記載したのち、リスタートするとログイン画面だけお洒落になった。
ファイルはscssなのに、なんでcssなのだろうと思いながら、scssに変更してサーバーを起動させたが、問題なく立ち上がった。cssとscssにはそんなに違いはないんだろうと勝手に解釈して終わった。なんとかうまくいってよかった。

学び

プログラミングを初めてから作業中の癖になっていたことが2つあり、1つはエラーが出たりわからなかったりするとすぐに調べるようになったこと。もう一つがteratailで誰かに助けを求めようとすることだった。が、そもそもどんなエラーなのか、しっかり突き詰めていないと調べて出てきた解決策が自分の課題とマッチしているのか判断ができないし、teratailで質問するにしても質問された側も状況の把握がうまくできない、何よりエラーの説明に答えがある場合がある、ということを今回の経験から学んだ。

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

Rails チュートリアル11章で躓いたポイント(未解決)

はじめまして

私は現在、職業訓練校で主にJava,C言語を学んでいますが、独学でRailsを学習中です。

今回は、タイトル通りRailsチュートリアルにて躓いたポイントを投稿しようと思います。

※2/11現在 問題は解決していません。

11章 本番環境でメールが送信できない!

11章リンク

development環境におけるアカウント有効化はおそらく進みテストもエラーなくクリアすることができました。

11.4 本番環境でのメール送信の項で問題が発生しました。

リスト11.41: Railsのproduction環境でSendGridを使う設定

  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  host = '<your heroku app>.herokuapp.com'
  config.action_mailer.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    :address        => 'smtp.sendgrid.net',
    :port           => '587',
    :authentication => :plain,
    :user_name      => ENV['SENDGRID_USERNAME'],
    :password       => ENV['SENDGRID_PASSWORD'],
    :domain         => 'heroku.com',
    :enable_starttls_auto => true
  }

上記リストを参考に、
  

  host = '<your heroku app>.herokuapp.com'

こちらの項目を https:から始まる自分のアプリのアドレスに変更
  
  
git & heroku にpush

$ git push
$ git heroku push
$ heroku run rails db:migrate

 
いざ、本番環境でユーザー登録!
※メールアドレスは切り抜いています。

sign op.png

すると

era.png

エラーしてしまいました。

試したこと

コードの見直しを行いおかしな箇所を探しましたが、これといったものは見つからず、
同じように躓いた人がいないか検索しました。

とりあえずログ確認してみる

herokuのログを確認すると、

$ heroku logs

  
COMMITはできていることが確認できました。
更にログをたどると
  

2020-02-11T05:46:41.907827+00:00 app[web.1]: Welcome to the Sample App! Click on the link below to activate your account:
2020-02-11T05:46:41.907828+00:00 app[web.1]: </p>
2020-02-11T05:46:41.907828+00:00 app[web.1]: 
2020-02-11T05:46:41.907829+00:00 app[web.1]: <a href="https://<アプリ名>.herokuapp.com/account_activations/ZbXtAXTWMPdPgdpu4EjcAQ/edit?email=<送信先アドレス>">Activate</a>
2020-02-11T05:46:41.907829+00:00 app[web.1]: </body>
2020-02-11T05:46:41.907829+00:00 app[web.1]: </html>

Activateリンクがあるのでそちらをクリック。

ok.png

認証はクリアできました。

なぜメールが送れないのか※予想

  
どうやらherokuからSendGridを登録すると凍結されるらしい

herokuからSendGrid ページにアクセスするも

スクリーンショット 2020-02-11 15.10.00.png

拒否されるのでおそらく凍結なのではと考えている。

SendGridユーザー登録して凍結解除の問い合わせしようと思います。

  

  
凍結解除で問題が解決されることを祈りつつ終わりとさせていただきます。
  
  
つたない文章ですがなにかの参考になれば幸いです。

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

DockerでRailsの環境構築

docker-composeでrails環境を構築します。データベースはpostgresqlを使用します。

Setup

以下のような構成からスタートします。

./
|- docker-compose.yml
|- rails-app/
  |- Dockerfile

Dockerfileの作成

Dockerfile
FROM ruby:2.5.0

RUN apt-get update && apt-get install -y build-essential libpq-dev postgresql-client vim less
RUN gem install rails -v '5.2.1'
RUN mkdir /app
WORKDIR /app

railsのバージョンは5.2.1を指定しています。
マウント先のディレクトリとしてappディレクトリを作成しておきます。

docker-compose.ymlの作成

docker-compose.yml
version: "3"

services:
  rails-app:
    build: rails-app
    ports:
      - "3001:3001"
    environment:
      - "DATABASE_HOST=db"
      - "DATABASE_PORT=5432"
      - "DATABASE_USER=postgres"
      - "DATABASE_PASSWORD=<パスワード>"
    links:
      - db
    volumes:
      - "./rails-app:/app"
    stdin_open: true

  db:
    image: postgres:10.1
    ports:
      - "5432:5432"
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=<パスワード>"

ポートは3001番を指定していますが、3000番でもOKです。

コンテナの起動

docker-compose build
docker-compose up -d

コンテナにログインします。

docker-compose exec rails-app bash

以降はコンテナ内で操作を行います。

Railsプロジェクトの作成

cd /app
rails new . -d postgresql -BT

-Bでbundle installをスキップし、-Tでテストファイルの作成をスキップしています。
Gemfileにtherubyracerを追加します。

Gemfile
gem 'therubyracer', platforms: :ruby

この状態でbundle installします。

bundle install —-path vendor/bundle

これでプロジェクトが作成されました。

データベースの設定

config/database.ymlを編集します。

  • defaultにhost, port, username, passwordを追加
  • データベース名を rails_app_development に変更
config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+ host: <%= ENV.fetch("DATABASE_HOST") { "localhost" } %>
+ port: <%= ENV.fetch("DATABASE_PORT") { 5432 } %>
+ username: <%= ENV.fetch("DATABASE_USER") { "root" } %>
+ password: <%= ENV.fetch("DATABASE_PASSWORD") { "password" } %>


development:
  <<: *default
- database: app_development
+ database: rails_app_development

データベースを作成します。

bundle exec rails db:create

起動

IPアドレスとポートを指定してサーバを起動します。

rails s -b 0.0.0.0 -p 3001

ブラウザでhttp://localhost:3001/を開いて、正しく起動できているか確認します。
スクリーンショット 2020-02-11 18.49.22.png

ホストPCとdockerコンテナ間でプロジェクトディレクトリを共有しているので(./rails-app:/app)、編集はホストPCで(vscode等で!)、実行は環境構築したコンテナで、という開発ができます。
幸せになりましょう。

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

rails migrate時にIncorrect table name

railsでcreateTableしたら以下の様なエラーが出ました。

エラー文

Mysql2::Error: Incorrect table name 'books  ': 

エラー箇所

    create_table "books ", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t|
      t.string "title", null: false
      t.string "author", null: false
      t.boolean "is_read", null: false
      t.datetime "discarded_at"
    end

原因

テーブル名の後ろにスペースが入ってました・・・

create_table "books "

普通に気づけそうなのですが、エラーがmysql2・・・と表示されていたため
特定に若干時間が掛かってしまいました。

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

【Rails】error prohibited this user from being saved:のエラーメッセージがi18nで日本語化されない

日本語化されない

下記のURLをもとにエラーメッセージを作成。
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml
template:
body: 次の項目を確認してください
header:
one: "%{modelにエラーが発生しました"
other: "%{model}に%{count}個のエラーが発生しました

しかしerror prohibited this user from being saved:のエラーメッセージだけが日本語化されない。

3fa1148b8a5369418ce366ab9e0515a3.png

結論

エラーメッセージ部分を下記のように変更する。
<%= t("errors.template.header", model: User.model_name.human, count: user.errors.count) %>

解決方法

最初、下記のようにエラーメッセージを書いていた。
<%= pluralize(user.errors.count,"error") %> prohibited this user from being saved:

下記のURL参照し書き直してみる。
http://artisan.hatenablog.com/entry/20110126/1296005216
<%=t "activerecord.errors.template.header.other", :model => Order.model_name.human, :count => @account.errors.count %>
otherという表示になる。

下記のURLを参照し、<%= t("errors.template.header", model: User.model_name.human, count: user.errors.count) %>と変更してみると適用できた。新しいバージョンで変更された?
https://qiita.com/yshr04hrk/items/cb7b81c104321f660661
「t("activerecord.models.user")と同じ
User.model_name.human #=> "ユーザ"」

https://github.com/svenfuchs/rails-i18n/issues/118
@kuroda I agree with @jrochkind, dynamic_form gem does not work for me.
Instead, this worked for me:
<%= t('errors.template.header', :model => Model.model_name.human, :count => model.errors.count) %>」

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

MacBookの環境 mysql5.6からmysql8.0に更新

やったこと

どこかで、rails6 色々変わりすぎてヤバイ!笑
っていう話を耳にして、そういえば開発環境に関してはスクールから言われるままに特定のバージョンを入れただけだな〜と思い確認すると案の定、古い安定バージョンを入れていた。自分は金がかからない限りは無駄に冒険してしまうところがあるので、Rails、Ruby、Mysqlをバージョンアップさせようと思いついてしまった。

ちなみにちなみに、自分は少数派のキチンとバックアップタイプですが、timemachineで外付けHDDにバックアップがある為、いつでも戻れる!という安心感の中でやりました。

新旧バージョン

app
Ruby 2.5.1 2.6.5
Rails 5.2.3 6.0.2.1
Mysql 5.6 8.0

※Rubyに関しては、最新2.7.0にしてしまうと、対応しているgemが少なくなってしまう為開発に甚大なダメージが・・・ということで、その前のバージョンで我慢しておく事にした。

RubyとRails

Homebrewをアップデートして、

  1. 最新バージョンをダウンロードしてきて、
  2. 最新バージョンをインストールして、
  3. 最新バージョンをデフォルト指定した。

Railsは旧バージョンをアンインストールしたかもしれない。Rubyはインストールしたバージョンを残しておけるみたい(brew??)。

実行したコマンドは忘れた。けど大して苦労はしてないハズ。

Rubyだけ、最新2.7.0にした時に既存アプリをrails startした時にエラーがいっぱい出てきて、それらのエラーはgemが未対応な事によるエラーだよ、っていう記事を見つけて考え直して2.6.5を入れたぐらい。

時刻設定

色々やって手順が前後する(Mysqlの設定にも関わる)が、まずRailsからMysql使ってた時に自動保存される時刻情報が無茶ずれてる(UTC時刻になってる)事が気に入らなかった。これに関してはRailsアプリを使っている時にRailsのプログラム内で日本時間に直すようなことをやっていたが、結局のところMysql自体にはUTC時間のまま保存されていたので、それを分かりやすく日本時間にしたかった。

デスクトップから右上に見える時刻表示(正常に日本時間表示)を気にしながら、コマンドラインでDateコマンドを打ってみると、なぜかUTC時刻になっていた。ひょっとしたらMacBookPro2017のデフォルトではJSTになっていたのかもしれないが、色々触りまくったので定かではない・・・

ということで、まずはシステム時間の修正から

システム時間(OS)

色々と調べた結果、システム時間の設定は /etc/localtime のバイナリファイルらしい。
更に、日本時間他各国のtimezone設定は /usr/share/zoneinfo/ にバイナリファイルがあり、日本時間の設定は /usr/share/zoneinfo/Japan のバイナリファイルらしい。

色々調べてたら、 /usr/share/zoneinfo/Asia/Tokyo っていう情報がいっぱい出てきたので必死にAsiaフォルダの中を探してたヨ。

$ sudo ln -s /usr/share/zoneinfo/Japan /etc/localtime
でdateコマンドがJSTで表示されるようになる。
※一般的にこういう操作する時は、 /etc/localtimeのバイナリファイルをバックアップとっておくらしい。自分はtimemachineでシステムバックアップとってるので気にしなかった。 

んで、あ〜安心と油断してたらデスクトップ右上の時間がこれまたメチャずれてた。なんでやねん、と思いながら "日付と時刻"環境設定を開く から時刻修正。

日付と時刻は、「日付と時刻を自動的に設定」にチェックを入れて、appleアジア(time.asia.apple.com)を選択。
時間帯は、「現在の位置情報に基づいて、時間帯を自動的に設定」のチェックを外してエリア選択で「日本」を設定した。

これで直ればいいが、すぐに時刻が設定されなかったので、なんとなくMACを再起動。
なんとか、デスクトップ右上の時刻も正常になった。

Mysql

時刻設定した後に、mysqlの時刻設定を見てみたらキチンと日本時間が適用されていた。

mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | JST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.02 sec)

Mysqlはバージョン共存する方法もあるらしいが、自分は旧の方はアンインストールした。

順に
旧をバックアップ、
旧をアンインストール、
(一応)再起動、
新をインストール、
my.cnf設定、
バックアップをリストア

バックアップ(エクスポート)

※後述するが、Mysql8.0に移行させる為にこの時のバックアップファイル(.sql)を編集するので、mysqldumpコマンドのオプションでなんとかできるならば、その方が楽。

$ mysqldump --single-transaction -u root -p -x --all-databases > 出力ファイル名

でいけるハズだけど、一時期うまく実行できなかった。
どういうコマンドで見たのか覚えていないが、データベースのプロパティをみる方法があり、--all-databases がFALSEになっていた。原因はよくわからないが、どこかの時点から --all-databasesができるようになっていた。よく分からん。

とりあえず、コマンド実行後に何も表示されないので、ちゃんと中身にクエリが入っているかは見ておいた方がいい

旧をアンインストール

単純な話、 brew uninstall mysql@5.6 を実行すればいいがゴミが残ってしまった事で何度もインストールを繰り返したので、きちっときれいにした方がいい。

$ brew uninstall mysql@5.6

どうしよう!困った時のMac上のMySQLのアンインストール&再インストール、動作確認手順

これの「Community Editionを削除する」「brew で入れたものを削除する」は何度やったか分からんぐらいやった。内容的に、「Community Editionを削除する」はやらんでいいかもしれんが、一応。

更にまた一応、Macを再起動。

インストール

// homebrewをアップデート
$ brew update
// インストールできるmysqlのバージョン確認
$ brew infomysql
// インストール
$ brew install mysql

my.cnf設定

ファイルの場所は覚えられないのに、my.cnfの候補ディレクトリを探すコマンドだけ覚えた

$ mysql --help | grep my.cnf
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf 

この内、自分は /usr/local/etc/my.cnfを使った。なぜなら4か所の内、そこにだけデフォルトでファイルがあったから。

/usr/local/etc/my.cnf
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
character-set-server=utf8
default_authentication_plugin=mysql_native_password
skip-slave-start
log_timestamps=SYSTEM

mysqlx-bind-address = 127.0.0.1
まではデフォルトで入力されてるので触らないようにする。

character-set-server=utf8
mysqlで日本語入力を可能にする

default_authentication_plugin=mysql_native_password
Mysql8.0からユーザー認証方法のデフォルトがcaching_sha2_passwordになってるらしい。これをやっておかないと多分うまくインポートできないし、Railsなんかに影響出そう。

skip-slave-start
なんかMysqlのログにエラー表示されてたので入れたが、結局ログにはエラーが残り続けてるのでよく分からない。入れなくてもいいかもしれない。Mysqlのバックアップをとる設定らしい。それを無視する。

log_timestamps=SYSTEM
Mysqlに保存されるログの時刻がこれまたUTCになっていたので日本時間にする為の設定。ちなみにログファイルは、/usr/local/var/mysql/マシン名.local.err にある。

インポートの前にユーザーの認証方式を変更

MySQL8系のDB接続エラーを解決する

ここを参考に、pluginの部分を全部mysql_native_passwordに。
ひょっとするとrootだけでいいかもしれない。

変え終わった後に他のコマンドを打とうとすると、確か警告が出てきてた。パスワードを設定しなさい、という。一旦適当なパスワードを設定して他のコマンドを実行できることを確認した上で、またパスワード無しを設定したが、いきなりパスワード無しでもいいかもしれない。

MySQL8でユーザーのパスワードの変更 / リセット方法

mysql> ALTER USER 'root'@'localhost' identified BY 'hoge';
mysql> ALTER USER 'root'@'localhost' identified BY '';

インポートの前にファイル修正

エクスポートの段階でとったバックアップファイルを三段階で修正(部分削除)した。
vi操作を調べとかないと厳しい。特に行削除操作。

viの基本操作

innodbに関する部分を削除

どこを見たのだったか忘れてしまった。。。これかな?
AWS Auroraでダンプしたデータをmysqlにインポートしようとしたらはまった

$ vi 保存したログファイル名.sql

削除した部分は、
-- Table structure for table `innodb_index_stats`
-- Dumping data for table `innodb_index_stats`
-- Table structure for table `innodb_table_stats`
-- Dumping data for table `innodb_table_stats`
の部分。

columns_privに関する部分を削除

これがさっきのページの情報だったか・・・
AWS Auroraでダンプしたデータをmysqlにインポートしようとしたらはまった

削除した部分は
-- Table structure for table `columns_priv`
-- Dumping data for table `columns_priv`
の部分。

mysqlデータベースのuserテーブルに関する部分を削除

これのヒントは、ユーザー認証の部分を説明してくれてたページ。

MySQL8系のDB接続エラーを解決する

削除した部分は
-- Table structure for table `user`
-- Dumping data for table `user`

バックアップデータの修正は以上。

:w 一応別名で保存.sql
:q!

バックアップをインポート

さっき保存したファイルを読み込み

$ mysql -uroot < 一応別名で保存.sql

これで、最新バージョンが使えるハズだけど、railsアプリを起動して問題なくMysqlが動くか確認しておくと安心。

Sequel Proが・・・

どういうわけか、Mysql8.0ではSequel Proが使えなくなるのでテストビルド版をインストールしないといけない・・・

MySQL8.0.x に Sequel Pro で接続する

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

bundle execって必要なの?

rails sって書いても、bundle exec rails sって書いても同じ動きをするように見えるんですが、何が違うのでしょうか。気になったので調べてみました。

結論

  • bundle execをつけないと、PCにグローバルインストールされているgemが動く
  • bundle execをつけると、そのプロジェクトで管理しているgemが動く
  • bundle exec railsbin/railsは同じ動きをする

そもそもBundlerとは

  • プロジェクト内で使うGemのパッケージ管理ツール。Gemをプロジェクト単位で管理することができる。
  • rbenv(rubyのバージョンをプロジェクト単位で管理するツール)のGem版
  • bundle installコマンドを叩くと、Gemfileに記載されたGemをインストールする

bundle installした時のGemの保存先

rbenvを使っている場合

$ gem which byebug
/Users/***/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/byebug-11.0.1/lib/byebug.rb

思ったこと

bundle execは毎回付けた方が良いってことですかね。
めんどくさいので、早く開発環境をdockerで管理したいです。
dockerを使えば、そのプロジェクト以外のことは全無視できるはず。

参考

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

【Rails】bundle exec rails db:seedを行って「localhost でリダイレクトが繰り返し行われました。」が出た時の対処法

エラー発生

db/seeds.rbの中身の変更を行い、bundle exec rails db:seedを行ったところ、「localhost でリダイレクトが繰り返し行われました。」のエラーが発生した。

ログは下記の通り。

Started GET "/login" for ::1 at 2020-02-11 15:40:29 +0900
Processing by UserSessionsController#new as HTML
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 13 LIMIT 1
  ↳ vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Redirected to http://localhost:3000/login
Filter chain halted as :require_login rendered or redirected
Completed 302 Found in 1ms (ActiveRecord: 0.3ms)

原因

下記のようにユーザーは10人にした。

db/seeds.rb
10.times do
  User.create(
      name: Faker::Name.name,
      email: Faker::Internet.email,
      password: '12345678'
  )
end

ユーザーカウントするとご覧のようになる。
irb(main):005:0> User.count
(0.4ms) SELECT COUNT(*) FROM users
=> 10

それに対してサーバーログ上ではUser Load (0.3ms) SELECT users.* FROM users WHERE users.id = 13となっており、13人目のユーザを取得しようとしている。
存在してないユーザーを取得しようとするができないためエラーになっている。自分でデータを入れたため、ユーザーが10人という上限を超えて存在していると思われる。

解決方法

下記コマンドを実行してユーザーを消去。(id内はユーザー数に応じて変えましょう)
User.where(id:1..13).destroy_all

その後再びbundle exec rails db:seedを行い、サーバーを再起動したところ、画面が正常に表示された。

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

[GAE][Rails]Note: Google::Cloud is disabled と表示される

事象

develop環境でrailsコマンドを打つと下記が発生

Your application has authenticated using end user credentials from Google Cloud SDK. We recommend that most server applications use service accounts instead. If your application continues to use end user credentials from Cloud SDK, you might receive a "quota exceeded" or "API not enabled" error. For more information about service accounts, see https://cloud.google.com/docs/authentication/. To suppress this message, set the GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS environment variable.
Note: Google::Cloud::Logging is disabled because the project ID could not be determined. Falling back to the default Rails logger.
Note: Google::Cloud::Debugger is disabled because the project ID could not be determined.
Note: Google::Cloud::ErrorReporting is disabled because the project ID could not be determined.
Note: Google::Cloud::Trace is disabled because the project ID could not be determined.

対象方法

とりあえずdevelop環境ではLogging等いらないと判断し下記の設定を追加しました。

config/enviroments/development.rb
  # gcp設定
  config.google_cloud.use_logging = false
  config.google_cloud.use_debugger = false
  config.google_cloud.use_error_reporting = false
  config.google_cloud.use_trace = false

参考

GAE/Rails で Stackdriver Logging を綺麗にするためにログの仕組みを学んだ
Rails — Disable Stackdriver in development

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

あんまり頭を使わないで構築するRailsAPI on Docker

すでに多くの記事がありますが、APIモードのRailsがDocker上で動くところまで、必要最小限の情報でまとめてみます。RubyMineでの設定も最後にちょっと書いてあります。

参考: 公式 Quickstart: Compose and Rails

ファイル準備

アプリケーションを作成したいディレクトリで設定ファイルを作成します。

 $ touch Gemfile Gemfile.lock Dockerfile docker-compose.yml entrypoint.sh 

各ファイルの内容を埋めます。

Gemfile

source 'https://rubygems.org'
gem 'rails', '~>6'

Dockerfile

FROM ruby:2.6
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app

# 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

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    ports:
      - 5438:5432
  app:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3008:3000"
    depends_on:
      - db
    environment:
      LANG: C.UTF-8
      BUNDLE_PATH: vendor/bundle
      RAILS_ENV: development
      DB_USER: postgres
      DB_NAME: app_db
      DB_PASSWORD: password
      DB_HOST: db

ファイルの内容ちょっと補足

  • Rubyは2.6、Railsは6系です
  • 公開するポートはrailsが3008、postgresqlが5438です
  • 後述するdatabase.ymlではwebサービスに設定した環境変数を読んで設定を行います

作る

$ docker-compose run app rails new . --force --no-deps --database=postgresql --api 
$ docker-compose build 

したら一通りRailsが必要なファイルを作ってくれます。自動で作成された database.yml を編集します。

database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: <%= ENV['DB_HOST'] %>
  username: <%= ENV['DB_USER'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  pool: 5

development:
  <<: *default
  database: app_development

test:
  <<: *default
  database: app_test
$ docker-compose run app rails db:create

動作確認

$ docker-compose up

http://localhost:3008/で動いてるはずです。

補足: RubyMine使ってる方、ちょろっと設定編

インタプリタの設定

Preferences > Languages & Frameworks > Ruby SDK and Gems

で、追加 > Docker Composeをクリック > OK

読み込みが完了したら、該当のSDKをチェックし、APPLYして完了です。補完がいい感じに効くようになります。

DB設定

Database > 追加 > Data Source > PostgreSQL

  • Host: localhost
  • Port: 5438
  • User: postgres
  • Password: password

で接続ができるはずです。うまくいかない場合は、タブから適切なスキーマを選択したり、DBが起動しているか確かめたりしてください。

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

rails s --port=3001 で別ポートでRailsサーバーを起動

コマンド

ターミナル
rails s --port=3001

上記のように入力すれば3001番のポートで、
Railsサーバーが起動します。
もちろん別のポートも利用可能。

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

【Rails】投稿とユーザーの紐付け(一対多)のメモ

経緯

現在ポートフォリオ用に「book memory phrase」というアプリを作っています。
自分が印象に残ったフレーズを引用した書籍とともに紹介して本との出会いを作る場です。

そこでユーザーと投稿の紐付けを行って、誰がどの投稿をしたか一覧で見れるような機能を実装したのですが、has_manyやbelongs_toなど学ぶことが多かったのでアウトプットしとこうと思います。

投稿したユーザーid

まずはデータベース上のidを紐付ける必要があります。

今回の場合だと、UserテーブルのidをPostテーブルに突っ込んで、誰の投稿かわかるようにします。

最初からこの機能は実装する気でいたので、Postテーブルを作る時点でidカラムとは別にuser_idカラムを作り、投稿する際にユーザーのidを突っ込めるようにしてました。

その辺については以前書いた【Rails】railsブログサイトの練習で躓いたところメモにも載せていますのでそちらを参考にしてもらえたらと思います。

Modelの設定

idが突っ込めたら次は紐付けです。これはModelで設定します。

has_many

has_manyは一対多の多の方です。
ユーザー1に対して投稿は多数あるので、ユーザーモデルにhas_manyを記述します。

user.rb
has_many :posts, dependent: :destroy

投稿は複数あるので複数系にしてください。

ちなみにdependent: :destroyはユーザーが削除されたら自動的に投稿も削除されるという優秀な機能です。

belongs_to

次は一対多の一の方、ユーザーの紐付けです。

post.rb
belongs_to:user

def user
   return User.find_by(id: self.user_id)
end

一の方はbelongs_toで紐付けられます。
また、userメソッドをモデルで定義しておけば汎用性が高くなるので書いときます。

Controllerの設定

私はuser_showというページで該当ユーザーの投稿一覧を表示したかったので、コントローラーに以下のように記述しました。

home_controller.rb
before_action :set_post, only[:user_show, :edit, :update, :destroy]

#省略

#@userにモデルで定義したuserメソッドを@post.userで代入
#@postsに@userの投稿を全て代入
def user_show
   @user = @post.user
   @posts = @user.posts
end

#省略

private
#Post.find_by(id: params[:id])はよく使うので定義しといてbefore_actionで反映。
def set_post
   @post = Post.find_by(id: params[:id])
end

これでコントローラーの準備は整いました。

Viewの設定

コントローラーで作った@postsをeach文で回してあげれば一覧が確認できます。

user_show.html.erb
<% @posts.each do |post| %>
   <div class="book-img col-lg-4 col-md-6 col-sm-12 center-block mx-auto">
      <div class="box">
         <div class="image-box">
            <h5><%= post.phrase %></h5>
            <p class="name">
               <span>投稿者&ensp;&ensp;</span><%= link_to("#{post.post_user}", "/home/#{post.id}/user_show")%>
            </p>
            <img src='<%= post.book_image %>' class="img-fluid d-block">
         </div>
         <div>
            <p class="title">
               『<%= post.title %>』
            </p>
            <p class="author">
               著者 <%= post.author %>
            </p>
            <p>★ おすすめポイント</p>
            <p class="content">
               <%= post.content%>
               <% if user_signed_in? && current_user.id == post.user_id %>
                  <span class="edit-delete">
                  <%=link_to("編集" , "/home/#{post.id}/edit",class:"text-muted") %>
                  <%=link_to("削除" , "/home/#{post.id}/destroy",method: :post,class:"text-muted") %>
                  </span>
               <% end %>
            </p>
         </div>
      </div>
   </div>
<% end %>

まとめ

投稿の紐付けは必須機能ですが、結構躓くところでもあると思います。

かく言う私も何度も躓いたのですがSQLを勉強したら結構スッと入ってこれました。
イメージって大事ですね。

もしこの記事が誰かの助けになれたら幸いです。
ではでは。

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

WSLでRuby on Railsの環境構築

やること

  • windowsでUbuntuを使えるようにする
  • Rubyのインストール
  • Railsのインストール
  • DBのインストール

windowsでUbuntuを使えるようにする

Ubuntuの入れ方については既に多くの記事がでているので省略します。

Ubuntuを立ち上げたら、ユーザ名とパスワードを入れます。
その後、パッケージを最新にするため下記のコマンドを以下のコマンドを実行してください。

sudo apt update
sudo apt upgrade -y

Rubyのインストール

Rubyをインストールする前にバージョン管理のために、rbenvをインストールします。
下記のコマンドを実行してください

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc //パス設定と初期化
echo 'eval "$(rbenv init -)"' >> ~/.bashrc

ここで一旦終了し再び立ち上げ、下記のコマンドを入力しバージョンが返ってきたらokです。

rbenv -v

ruby-buildのセットアップとパッケージのインストールをします。

git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev

ここからRubyのインストールです。

rbenv install 2.6.5
rbenv global 2.6.5 
ruby -v
which ruby

ruby -vを実行して返ってきたらokです。

さらに、gemのアップデートとbundlerのインストールもしておきます。

gem update
gem install bundler

Railsのインストール

gem install rails -v 6.0.2
rails -v

ここでもバージョンが返ってきたらokです。

後に必要となるnode.jsもここでインストールしておきます。

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - //バージョンは最新のものを選択してください。
sudo apt install nodejs

DBのインストール

下記のコマンドを実行してください。

sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ 18.04.4 -pgdg main" >/etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
sudo apt install postgresql
psql -V

バージョンが返ってきたらokです。

Postgresqlを起動します。

sudo service postgresql start
sudo su postgres -c 'createuser -s ユーザ名'
psql postgres

\qを入れて終了します。
下記のコマンドで「pg」が利用するパッケージをインストールしておきます。

sudo apt install libpd-dev

参考文献

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

railsの環境構築 その1

はじめに

これからdockerで開発環境の構築からAWSデブロイまで数回に分けてまとめてみます

私が使った有料教材

Dockerについて

Dockerについては下記のサイトを見てください。
* 入門 Docker

Dockerでrailsの環境構築

参考

作業手順

ディレクトリを作成しそこで作業

mkdir ror_app

Dockerfileを作成Dockerfile内に下記を記述

touch Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# 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

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

コマンド

FROM: ベースとなるDocker Image を指定します。
COPY: Docker内へホストのファイル/ディレクトリをコピーします。
  COPY は基本的に2つの引数を設定します。1つ目はホスト側のディレクトリ、2つ目はDocker側のディレクトリです。
RUN: Docker内でコマンドを実行します。
CMD: Docker起動時にデフォルトで実行されるコマンドを定義します。
WORKDIR: Dockerfileでコマンドを実行する際に基準となるディレクトリを設定します。
EXPOSE: コンテナ起動時に公開することを想定されているポートを記述します
ENTRYPOINT: 指定されたコマンドを実行します。

GemfileとGemfile.lockの作成

  • rails newするときに必要
touch Gemfile && touch Gemfile.lock
source 'https://rubygems.org'
gem 'rails', '~>5'

entrypoint.shを作成

  • 特定のserver.pidファイルが存在するときにサーバーが再起動しないようにするRails固有の問題を修正するエントリポイントスクリプトを提供します。このスクリプトは、コンテナが開始されるたびに実行されます。
  • touch entrypoint.sh
entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

docker-compose.ymlの作成

touch docker-compose.yml
docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    ports:
      - '5432:5432'
    volumes:
      - postgresql-data:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  postgresql-data:
    driver: local

docker上でrailsのファイルを作成

docker-compose run web rails new . --force --no-deps --database=postgresql

# rails new . とすることで、カレントディレクトリ配下にrailsファイルが作成される  
--forceで事前に作成したファイルを上書き、今回はGemfile等

gem 'pg'のバージョン変更

gem 'pg', '~> 0.20.0'

イメージをbuild

docker-compose build

すると

ror_app_web:latestになります。

databese.ymlの書き換え

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5
# host,username,passwordを追加しました。
hostをdbにすることでdocker-compose.ymlのdbを指定

本番環境や開発環境でdatabase関連のエラーが良く出てきます。
特に本番環境をAWSにするとproduciton:配下を書き換えないといけません。

データベースの作成

docker-compose run web rake db:create

サービスの起動

docker-compose up
# 終了はCtrl+C

ブラウザでlocalhost:3000にアクセスするとrailsの初期画面が出現したと思います。

docker-composeコマンドまとめ

ローカル環境 docker環境
rails s docker-compose up
rails db:migrate docker-compose run web rails db:migrate
bundle install docker-compose run web bundle install
rails g model モデル名 docker-compose run web rails g model モデル名

git push

railsの初期画面が出てきたらgit pushしておきましょう。

お疲れさまでした。

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

【Rails】I18n::InvalidLocaleDataが出た時の対処法

gemのi18nを導入し日本語化していると、下記のエラー(I18n::InvalidLocaleData
)が発生しました。

Screenshot from Gyazo

対処法

view側で間違いがない場合、ja.ymlの記述が間違っている可能性が高いです。
viewのエラーが出ている箇所を消してみて同じエラーが出るようなら、そもそもファイルが読み込めてないので、ja.ymlの記述を確認しましょう。
私がよくやっていた間違いが2つあります。

①ディレクトリのミス
本来のディレクトリと違っていた、sのつけ忘れなどスペルミス。ディレクトリ通りか確認しましょう。

②インデントミス
他のファイルではインデントが違っても表示されますが、ja.ymlファイルでは1つでもインデントが違うと読み込まれません。ディレクトリの階層ごとにちゃんとインデントがされてるかチェックしてください。

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

VSCodeのRailsのフォーマッタはBeautifyがオススメ

VSCodeでRailsのコードを書いていて、フォーマッタを使うといいと言われました。どのフォーマッタがいいか迷ったり導入に戸惑ったので、今回はおすすめの「beautify」について紹介したいと思います。

Rufoを導入しようと試みるも...

「Rails」「フォーマッタ」で検索するとRufoが出てきた。
https://qiita.com/totto357/items/31552e899b737b529244

毎回コマンドラインでフォーマットをかけるか、.rufoの設定をする必要がある→初心者にはわかりづらい...

Beautify導入

他にないかと検索すると「beautify」 発見。
https://qiita.com/giosc103/items/3da5d172cbbb574a9352

上記のURL通りMarketplaceでインストールする。
もともとjavascript用なので、settigs.jsonで

"beautify.language": {
・・・
        "html": [
            "htm",
            "html",
            "erb"
        ]
    }

こうすることでerbファイルで保存する際、勝手にフォーマットを修正してくれる。
設定するものも少なく自動で修正してくれるので、Rails勉強しているプログラミング初心者におすすめ。

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

VSCodeのRuby on RailsのフォーマッタはBeautifyがオススメ

VSCodeでRuby on Railsのコードを書いていて、フォーマッタを使うといいと言われました。どのフォーマッタがいいか迷ったり導入に戸惑ったので、今回はおすすめの「beautify」について紹介したいと思います。

Rufoを導入しようと試みるも...

「Rails」「フォーマッタ」で検索するとRufoが出てきた。
https://qiita.com/totto357/items/31552e899b737b529244

毎回コマンドラインでフォーマットをかけるか、.rufoの設定をする必要がある→初心者にはわかりづらい...

Beautify導入

他にないかと検索すると「beautify」 発見。
https://qiita.com/giosc103/items/3da5d172cbbb574a9352

上記のURL通りMarketplaceでインストールする。
もともとjavascript用なので、settings.jsonで

"beautify.language": {
・・・
        "html": [
            "htm",
            "html",
            "erb"
        ]
    }

こうすることでerbファイルで保存する際、勝手にフォーマットを修正してくれる。
設定するものも少なく自動で修正してくれるので、Rails勉強しているプログラミング初心者におすすめ。

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

Rails6にバージョンアップしたらscopeからprivate class methodを呼び出せなくなった

問題

Rails5.1から5.2にバージョンアップすると、ActiveRecordのscope内からprivate class methodを呼び出すとワーニングが出るようになりました。
Rails6までバージョンアップするとscope内からprivate class methodを呼び出せなくなりました。

class Post < ApplicationRecord

  scope :recent, -> {sort_order}

  class << self

    private

    def sort_order
      order(:updated_at)
    end
  end
end

Rails5.2で上記のPost.recentを実行すると以下のエラーが出ます。

Rails5.2

DEPRECATION WARNING: Delegating missing recent method to Contact. 
Accessibility of private/protected class methods in :scope is deprecated and will be removed in Rails 6.0.

Rails6.0

NoMethodError (undefined method `recent' 
for #<Post::ActiveRecord_Relation:0x0000563ecd045440>

原因

Rails6.0からは名前付きscope内のレシーバがクラスオブジェクトからrelationオブジェクトに変更となります。

The receiver in a scope was changed from klass to relation itself
for all scopes (named scope, default_scope, and association scope)
behaves consistently in #29301.

Unable to access private class methods from a Scope #38405
Bring back private class methods accessibility in named scope #32355

class Post < ApplicationRecord

  scope :recent, -> {sort_order}

  class << self

    private

    def sort_order
      order(:updated_at)
    end
  end
end

ここで宣言しているsort_orderメソッドは、Postクラスオブジェクトに対して追加しているprivate class methodになります。
Rails5.1では、名前付きscope内のレシーバがクラスオブジェクトであるため、クラスオブジェクトに所属するsort_orderメソッドがレシーバ省略の形で呼び出せていました。

Rails6.0以降は、名前付きscope内のレシーバがrelationオブジェクトに変更となるため、sort_orderと書くだけでは呼び出せなくなります。
sort_orderはrelationオブジェクトではなく、Postクラスオブジェクトに所属するため)

解決方法

Rails5.2、Rails6.0ではsendメソッドを使ってscope内からprivate class methodを引き続き呼び出すことができます。

class Post < ApplicationRecord

  scope :recent, -> {Post.send(:sort_order)}

  class << self

    private

    def sort_order
      order(:updated_at)
    end
  end
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[-bash: rbenv: コマンドが見つかりません�]aws(ec2)上のrbenvの初期設定エラーの解決方法

1.エラーの内容

Neverland:.ssh kontatomoya$ ssh -i freemarket_sample_62d.pem ec2-user@3.115.38.38

Last login: Mon Feb 10 20:51:18 2020 from xx000000000000.au-net.ne.jp

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
-bash: rbenv: コマンドが見つかりません
#↑ec2に接続した時に出るこのエラーが本題です
[ec2-user@ip-000-00-00-00 ~]$ 

2.考えられる原因

1.そもそもrubyに関する環境構築をしていない

2.環境構築の際コマンドの順番を誤り.bash__profileでサーバーサイドが想定した記載になっていない。(自分が確認した限りではデプロイしたアプリへの影響はありませんでしたが、どこでバグの原因となるかわからないため解消することを推奨します)

3.解決方法

1.そもそもrubyに関する環境構築をしていない

この場合は下記の手順に従ってコマンドを打ち込むことで解消します
中途半端に設定した方はひとまず指示に従って全て打ち込んでください(ダブってしまう不要な箇所を4.で確認および削除し解決します。一度アプリケーションをデプロイして、再度違うアプリケーションをデプロイし直す方も同様にしてください)

[ec2-user@ip-000-00-00-00 ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv 
#rbenvをEC2にインストール
[ec2-user@ip-000-00-00-00 ~]$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile 
#パスを通すための記述を.bash_profileに追記
[ec2-user@ip-000-00-00-00 ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
#rbenvを呼び出すための記述を.bash_profileに追記
[ec2-user@ip-000-00-00-00 ~]$ source .bash_profile
#.bash_profileをEC2に読み込み
[ec2-user@ip-000-00-00-00 ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
#ruby-buildのインストール
[ec2-user@ip-000-00-00-00 ~]$ rbenv rehash  
#rehashを行う
[ec2-user@ip-000-00-00-00 ~]$ rbenv install 2.0.0
#rubyのインストールを行う(2.0.0は自分のアプリのrubyバージョンに合わせる)
[ec2-user@ip-000-00-00-00 ~]$ rbenv global 2.0.0
#rubyをEC2上共通のバージョンとする
[ec2-user@ip-000-00-00-00 ~]$ rbenv rehash 
#rehashを行う
[ec2-user@ip-000-00-00-00 ~]$ ruby -v 
#バージョンを確認→"ruby 2.0.0p648 (2015-12-16) [x86_64-linux]"が出ればok

#設定の内容を見たい場合は下記コマンド
[ec2-user@ip-000-00-00-00 ~]$ vim ~/.bash_profile
#.bash_profile(初期設定の隠しファイル)をviエディターで確認する
2.環境構築の際コマンドの順番を誤り.bash__profileでサーバーサイドが想定した記載になっていない。

エラーを起こしている.bash__profileファイルは下記のようになっています

[ec2-user@ip-000-00-00-00 ~]$ vim ~/.bash_profile
#.bash_profile(初期設定の隠しファイル)をviエディターで確認する
.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH
eval "$(rbenv init -)"
export PATH="$HOME/.rbenv/bin:$PATH"
#↑環境構築のコマンドにより最下の行を追記しました。正しいコマンド通りだとした2行が逆転していなければなりません

コメントに従って下記の行を入れ替えることで正しい環境構築となります。エラーの理由はパスを通す前にrbenvを呼び出す記述となっているからでした。

4.中途半端に設定したあとにコマンドをした方の重複箇所のと確認と削除について

rbenv の環境構築で重複する箇所は.bash_profileだけなのでそちらを下記コマンドで確認し、一番最後に記載した.bash_profileのテンプレートと異なる部分の削除を行なっていただくことで正しく設定できます。

※また、注意点として、ローカルの.bash_profileとEC2(サーバー側)の.bash_profileは記載内容が異なり、今回は全てEC2(サーバー側)で作業を行なうようにしてください。

[ec2-user@ip-000-00-00-00 ~]$ vim ~/.bash_profile
#.bash_profile(初期設定の隠しファイル)をviエディターで確認する

※1.でなぜもう一度全て打ち直していただいたかというと.bash_profileにrubyやruby-buildが入っているか表示されないため、インストールされず進んでしまうおそれがあるからです。また、rubyやruby-buildは何度インストールしても自動でダブらないようにしてくれるため重複は気にしなくて大丈夫である(alreadyの文が出ます)ため、記載漏れしないように再度全て記述していただきました。(慣れている方はruby -vで環境の有無の確認の後.bash_profileに手打ちでもいいのですが、初期設定のファイルの存在自体がわかりにくく、これを見られているのは初学者の方が多いと思うのでコマンドから打って、最後に不要部分を削ることをお勧めします。)

<.bash_profileのテンプレート>

.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

以上の方法でエラー文は解消されます

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

herokuにデプロイするときの単純ミス

Railsで作成したアプリをHerokuでデプロイしようとした時のミス
スクリーンショット (318).png

terminal.
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !     Detected sqlite3 gem which is not supported on Heroku:
remote:  !     https://devcenter.heroku.com/articles/sqlite3
remote:  !

結論

Gitリポジトリにデプロイするためgemを変更した修正を上げていなかった。。。
githubのリポジトリからデータがHerokuに送られているため、githubのコードを更新しなければならない!!!!!(そう言えばそうだった笑)

terminal.
$ git add *
$ git commit -m 'add to gemfile(メッセージは何でもいい)'
$ git push
$ git push heroku master

解決方法

HerokuにデプロイするときはたいていRails Tutorialを参考にしています。
Rails Tutorial "1.5デプロイする"

Gemfile.
group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

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

・gem 'sqlite3'
・gem 'pg'
を挿入してgit push する!

terminal.
remote: Verifying deploy... done.

無事デプロイできました!

簡単なミスしないようにしたい。。。:sob:
これからも頑張ろう!

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