技術ブログっぽいなにか

Ruby・Railsメインでいろんなこと書きます

Railsが依存するgemの脆弱性が見つかったので対処する

Github見たらこんなのがでていた。

f:id:tmicha:20180722175602p:plain

Gemfile.lockに書いてあるgemにXSS脆弱性が見つかったからアップデートしたほうがいいよ!っていう通知らしい。

最近のGithubめちゃ親切ですね。

今回対象のgemは4つ

f:id:tmicha:20180722175758p:plain

なので、

$ bundle update loofah
$ bundle update nokogiri
$ bundle update rails-html-sanitizer
$ bundle update sprockets

を実行して、 commit & push で終わり。

Macのアカウント名とホームディレクトリ名変えたらいろいろ大変だった

もう3年くらい使っているMacbookのユーザー名(とホームディレクトリの名前)が本名のままで、
なんとなく嫌だし変えたいな〜と思ったので、公式を参考に変えてみた

support.apple.com

そしたらいろいろと大変だった。

大変なことその1:そもそもうまく変更ができない

公式を見ながらやっていたのに、変更できているのではなく新しいユーザーができてしまっていてめちゃくちゃ焦った。

ので、他の人のブログを参考にやってみたらできた。
参考にしたのはこちら↓

ringo-master.com

違いとしては、こちらの方のブログでは、公式で紹介されている作業にプラスして
FinderでUserフォルダの名前を直接変更している点。

私も直接いじったら無事に変更できました。
OSが古いのがいけないのかな?でもSierraなんですけどね。

大変なことその2:シェルのカスタマイズがもとに戻ってしまった

私はzshを使っていて、かつPreztoっていうライブラリを使ってカスタマイズしているんですが
これのシンボリックリンクが古いユーザー名のパスのままで、設定ファイルが反映されていなかったというのが原因。

$ ls -al

すると

lrwxr-xr-x     1 user-name  staff      45  7 22 15:04 .zlogin -> /Users/user-name/.zprezto/runcoms/zlogin
lrwxr-xr-x     1 user-name  staff      46  7 22 15:04 .zlogout -> /Users/user-name/.zprezto/runcoms/zlogout
drwxr-xr-x    10 user-name  staff     340  2 13  2017 .zprezto
lrwxr-xr-x     1 user-name  staff      48  7 22 15:04 .zpreztorc -> /Users/user-name/.zprezto/runcoms/zpreztorc
lrwxr-xr-x     1 user-name  staff      47  7 22 15:04 .zprofile -> /Users/user-name/.zprezto/runcoms/zprofile
lrwxr-xr-x     1 user-name  staff      45  7 22 15:04 .zshenv -> /Users/user-name/.zprezto/runcoms/zshenv
lrwxr-xr-x     1 user-name  staff      44  7 22 15:04 .zshrc -> /Users/user-name/.zprezto/runcoms/zshrc

こんな感じで、シンボリックリンクが張られているのがわかる。
なので、新しく張り直す。

$ ls -nfs /Users/new-user-name/.zprezto/runcoms/zpreztorc .zpreztorc

みたいな感じで、ひとつずつ変えていけばOK。

大変なことその3:ライブラリなどの参照先パスが古いままなので動かない

変更後、rails s しようとしたらそんなコマンドねえぞって怒られていて、よく見たら古いユーザー名でのパスがエラー文に表示されていた。

これ多分もうrbenvに限った話ではなくて、今ここだけ直してもこの先エラーのたびに修正し直すのを何回もやらないといけないんだなと思って絶望しました。。

古いユーザー名でgrepしたらめちゃくちゃたくさん出てきたし、もうもとに戻そうって決めた…

ちなみに一括で置換する方法もあるみたいだけど、失敗すると多分死にたくなると思います。

teratail.com

まとめ

という感じで、ホームディレクトリやユーザー名は軽率に変更しないほうがよいということを学びました。
特に開発者とか、外部からライブラリなんかを持ってきて使う人はやめたほうがいいですね。 そういうの全部$HOMEとかシェル変数でできればいいんだけどなあ。

参考

qiita.com

Herokuにpushできたのにアプリケーションが動作してなかった

Railsプロジェクトがデプロイできるところまで作れたので
試しに作業中のブランチを(まだmasterにmergeしてないので)pushしてみるか!と思ってやってみた

$ git push heroku <branch-name>

のはいいんだけど、heroku createしたときの灰色の画面のままだった…

結論

pushした時のコマンドが間違っていたので
正しくpushができていなかった(泣

試したこと

1. migrateする

例の灰色の画面(スクショ撮り忘れた)のままだったので とりあえずmigrateしてみる

$ heroku run rails db:migrate

rails db:createはpush時にやってくれるけど migrateは自分でやらないといけないのでね

そしたらrails: command not foundって言われた

2. bundle install する

railsがないってことはbundle installしたらよい?

$ heroku run bundle install

結果、bundle: command not found

ほんとうに…?

3. gem install bundler する

bundle コマンドが叩けないってことはbundler がないってことなので bundlerインストールしたらよい?

$ heroku run gem install bundler

そしたら今度はpermissionがなんとかって言われてエラーになった(どんなエラーかあんま覚えてない)

4. ファイル構成を確認する

permissionとか言われたから管理者だれになってるんだろう?と思って確認してみた

$ heroku run ll

llコマンドはls -lのことですね。
結果なにも返ってこなかったので、「空ってことはpushがうまくできてないのでは!?」ということに気がついた…!!!

解決策

$ git push heroku <branch-name>

をもう一度実行してみる
と、問題なくpushはできる…特にエラーになったりはしていない模様…

調べていたところ、master以外のブランチをpushする時は

$ git push heroku <branch-name>:master

じゃないといけないということがわかった!!!!

ようするに、「どのブランチを」「どのブランチに」pushするのかを指定しないといけなかったっぽい。 普通に考えたら当たり前ではある。

$ git push heroku branch-name:master

で、ちゃんと表示できました!!!

pushがエラーにならずにできていたのは確かにその通りで、
でもHerokuがアプリケーションとして公開しているのはmasterブランチだけなので、例の灰色の画面が出ていた、という…。

確かにHerokuってmaster以外のブランチ指定してstaging環境とか作れますもんね。

補足

GitHubにpushするときも、

$ git push origin master

とかやるんだけど、
これって実は内部的には

$ git push origin master:master

をやっている。
同じ名前のブランチにpushする時は省略できるけど、そうじゃないときはちゃんと指定してねってことでした。

おわり。

deviseのflashをBootstrap対応にする

deviseとBootstrapを組み合わせて使っていると、deviseとBootstrapで表現が違うため色がいい感じにならない時がある
での、それを解決します

application.html.erb

<% flash.each do |name, msg| %>
    <div id="alert" class="col-xs-11 alert alert-<%= bootstrap_class_for(name) %> alert-dismissible fade" >
      <a class="close" data-dismiss="alert" aria-label="Close">×</a>
      <%= msg %>
    </div>
<% end %>

application_helper.rb

module ApplicationHelper
  def bootstrap_class_for(flash_type)
      case flash_type
          when "success"
          "success"
          when "error"
          "danger"
          when "alert"
          "warning"
          when "notice"
          "info"
          else
          flash_type.to_s
      end
  end
end

こうしておくと、これから色の種類が増えても修正が楽になるね!

参考

hitori-programming.org

【Active Record】値が保存できなかった

メッセージがお気に入りされたらFavoriteテーブルにそのメッセージのidが保存されるようにしたかった
けど、なぜか保存されなかった。

関係ありそうな場所

Controller

class FavoriteController < ApplicationController

  def create
    @user_id = current_user.id
    @favorite = Favorite.new(message_id: params[:id], user_id: current_user.id)


    if @favorite.save
      redirect_to home_path, success: 'お気に入り登録しました!'
    else
      redirect_to home_path, danger: 'お気に入り登録ができませんでした'
    end
  end

  def destroy
    @favorite = Favorite.find(params[:id])
    if @favorite.destroy
      redirect_to home_path
    end
  end

end

createメソッドがうまくいってないっぽい。

原因

カラム名が複数形になっていた。
他テーブルの主キーとジョインするカラムは テーブル名(単数系)_idじゃないとダメらしい
参考:データベースオブジェクトの命名規約 - Qiita

ActiveRecord::Schema.define(version: 20171231015724) do

  create_table "favorites", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer  "user_id",    null: false
    t.integer  "messages_id", null: false  #<=ここ
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["message_id"], name: "index_favorites_on_message_id", using: :btree
    t.index ["user_id"], name: "index_favorites_on_user_id", using: :btree
  end

  create_table "messages", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer  "user_id"
    t.string   "contents"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
  end

end

解決策

$ rails g migration RenameMessagesIdColumnToFavoritesマイグレーションファイルを作ってmigrateする。

class RenameMessagesIdColumnToFavorites < ActiveRecord::Migration[5.0]
  def change
    rename_column :favorites, :messages_id, :message_id
  end
end
$ rails db:migrate

終わり。

Rails命名規則、あんまり覚えていないせいでいちいちググっているので、ちゃんとまとめたい…

参考

qiita.com

HerokuのDBをPostgreSQLからMySQLに変更する


Railsでアプリ作ってて、デフォルトのPostgreSQLを使ってたけど
中身をSequelで見たいなあと思ったのでPostgreSQLからMySQLに変更することにした。


ググったらたくさん記事が出てくるからラクショーじゃん!と思っていたけどかなり時間がかかってしまったし、
次も同じ目に遭いそうだなと思ったのでメモ。

Gemfileにmysqlを追加する

#gemfile
gem 'mysql2',       '~> 0.3.20'

database.ymlの設定を変更する

#database.yml
default: &default
  adapter: mysql2
  pool: 5
  timeout: 5000

development:
  <<: *default
  adapter: mysql2
  database: appname_development
  pool: 5
  timeout: 5000

# 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

production:
  <<: *default
  adapter: mysql2
  pool: 5
  timeout: 5000

bundle installする

$ bundle install

ここでGemfile.lockに差分ができるので、Gemfileとともにコミットする。
私はこれをやってなくて2日くらい悩んでいた。なんと無駄な・・・
うまくいったらHerokuにpushする。

HerkouのアドオンにClearDBを追加する

$ heroku addons:add cleardb 

もしかしたらアプリ名指定しろよって言われるかも?

DATABASEの設定を削除する

$ heroku addons:destroy heroku-postgresql -a appname

ググった時に出てくる記事だとheroku addons:detach DATABASE -a appnameでもいいっぽいのだけど、それだとなぜか通らなかった。 destroyだといけた。 アプリの名前入れてくれーって言われるので入れてあげると削除してくれる。

DATABASE_URLをCLEARDATABASE_URLのものに書き換える

$  heroku config:set DATABASE_URL='mysql2://xxxxx?reconnect=true' --app appname

mysqlmysql2に変えることを忘れずに。

いちおうdb:migrateしてheroku openする

$ rails db:migrate
$ heorku open




おわり。
大変だった…また次もつまづきそうだ…

Herokuにデプロイしたら背景が真っ白になった話

 

久しぶりにHerokuにサイトをデプロイしたら背景が真っ白になった。

あーこれ知ってる。アセットプリコンパイルだ。
でも背景以外の画像はちゃんと表示できてる。

とりあえずコマンド叩いてみた。 

~/w/r_portfolio ❯❯❯ heroku run rake assets:precompile
Running rake assets:precompile on ⬢ tsumi-portfolio... up, run.9433 (Free)
Error waiting for network: Resource temporarily unavailable
~/w/r_portfolio ❯❯❯ heroku run rake assets:precompile
Running rake assets:precompile on ⬢ tsumi-portfolio... up, run.7788 (Free)


実はこのコマンド叩いたの1年前が最初で最後で、
記憶を頼りに適当に叩いたら合っててびっくりした。

まあ、うまくいかなかったけど。

一応ググったら環境変数指定しないといけなかったっぽい。
それのせいなのか、怒られているリソースがなんとかってせいなのかはわからない。


production.rbの設定変えるらしい

ということがわかったので、production.rbを開いてconfig.assets.compileを確認。


falseになってた・・・

f:id:tmicha:20170918163844p:plain

なおして再びpush。

解決!