TECH EXPERT 46日目

TECH::EXPERT

rails

foreign_key bigint

usersテーブルを設定したあと、t.referencesで外部キーを持つテーブルを作成した際にuser_idがbigint(20)になって外部キーが貼れない。(integer型と型が違うから)

  def change
    create_table :shippings do |t|
      t.references     :zipcode, foreign_key: true
      t.timestamps
    end

外部キーを含まない状態でcreate_tableしたのち、add referenceすれば型違いは吸収される。

class CreateShippings < ActiveRecord::Migration[5.2]
  def change
    create_table :shippings do |t|
      t.integer     :zipcode, null: false
      t.timestamps
    end
    add_reference :shippings, :user, foreign_key: true, null: false
  end
end

migrationの順番で外部キーがないと怒られるのでmodel作成順に注意する。
適当な順でmodelを作る場合は、外部キー以外のテーブルを作成して、別途外部キーを最後にadd_tableする。

rake db:reset

全てのテーブルをドロップして、shemaを元にmigrateする。

rake db:migrate:reset

全てのテーブルをドロップして、migrationファイルを元にmigrateする。

rake db:rollback

1つ前のmigration状態へ戻る。

rake db:version

現在のmigrationの位置を見れる。

mysql

indexを張るとmul型になる。外部キーと同じ表記なので紛らわしいがindexの意味にとってOK

S3

バケット作成

バケットポリシーの設定(下2つをオン)

IAMユーザーのARN情報をコピーする

S3バケットのアクセス権限・バケットポリシーに以下を追記

{
    "Version": "2012-10-17",
    "Id": "Policy1544152951996",
    "Statement": [
        {
            "Sid": "Stmt1544152948221",
            "Effect": "Allow",
            "Principal": {
                "AWS": "************①****************"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::************②**********"
        }
    ]
}

①に先ほどメモしておいたユーザーのARNを、②に作成したバケット名を記述

例
{
    "Version": "2012-10-17",
    "Id": "Policy1544152951996",
    "Statement": [
        {
            "Sid": "Stmt1544152948221",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789123:user/upload_user"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::upload-app-test"
        }
    ]
}

awsで環境変数を設定

vim ~/.bash_profile
export AWS_SECRET_ACCESS_KEY='ここにCSVファイルに乗っている値をコピー'
export AWS_ACCESS_KEY_ID='ここにCSVファイルに乗っている値をコピー'
source ~/.bash_profile

deproy.rbを編集

# secrets.yml用のシンボリックリンクを追加
set :linked_files, %w{ config/secrets.yml }

# 元々記述されていた after 「'deploy:publishing', 'deploy:restart'」以下を削除して、次のように書き換え

after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end

  desc 'upload secrets.yml'
  task :upload do
    on roles(:app) do |host|
      if test "[ ! -d #{shared_path}/config ]"
        execute "mkdir -p #{shared_path}/config"
      end
      upload!('config/secrets.yml', "#{shared_path}/config/secrets.yml")
    end
  end
  before :starting, 'deploy:upload'
  after :finishing, 'deploy:cleanup'
end

secrets.ymlからcredentials.ymlに変わっているので、以下のように記述を変更。

secrets.yml
aws_access_key_id: Rails.application.secrets.aws_access_key_id,
aws_secret_access_key: Rails.application.secrets.aws_secret_access_key,

credentials.yml.enc
aws_access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
aws_secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key),

rails

ベーシック認証 Basic認証

HTTP通信の規格に備え付けられているユーザー認証

authenticate_or_request_with_http_basic

下記の例ではusernameとpasswordを設定している。
ソースにベタ書きではなく、普通は環境変数を使う。

authenticate_or_request_with_http_basic do |username, password|
  username == 'admin' && password == 'password'
end

実際に動かすにはbefore actionで呼び出す。
before_actionに付けるif文は、rails5.2以前はif: “Rails.env.production?”という記法が通用したが、5.2〜はproc{}で囲まないと弾かれるようになった。

class ApplicationController < ActionController::Base
  before_action :basic_auth, if: proc{Rails.env.production?}

  private
  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == 'admin' && password == '2223'
    end
  end
end

もしくはメソッドを定義してif文に書き込む。

  before_action :basic_auth, if: :production?  

  private
  def production?
    Rails.env.production?
  end
  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
    end
  end

コメント