91s

プログラミング関係、日記などを書きます

【Rails】activeadmin アクションボタンを消す方法

やりたいこと

f:id:isshi_pg:20200626171057p:plain
activeadmin 新規レコード追加ボタン

f:id:isshi_pg:20200626171440p:plain
activeadmin show 右上のボタン

これらを出さないようにする

やり方

ActiveAdmin.register AdminUser do
   config.clear_action_items! # ←これを追加
end

追記:特定のアクションだけ消す・残す方法

  • 一覧、詳細画面だけ表示
ActiveAdmin.register AdminUser do
  actions :index, :show
end
  • 編集画面、更新・削除権限なし
ActiveAdmin.register AdminUser do
  actions :all, except: [:edit, :update, :destroy]
end

参考文献

https://stackoverflow.com/questions/7815319/activeadmin-disabling-the-new-resource-method

【Rails】EC2再起動時にunicornを起動する方法

はじめに

EC2の再起動に合わせてunicornを起動する必要があったのでそのメモを残しておきます。

最初から再起動時を何かしらで取得してそのタイミングで実行したいコマンドを設定しておく というところまでは直感でわかりましたが、何を使うかは調べないとわかりませんでした。

調べたところcronに@rebootという再起動時を指定できる方法があったのでそれを使用しました。

実際の設定

crontab -eを実行して、

@reboot sudo nginx start && {unicorn_railsのフルパス} -c {unicorn.conf.rbのフルパス} -D -E {RAILS_ENV(環境変数に入っていれば指定しなくてもok)}

と設定します。 これでOKです。

設定できているか確認する際は、crontab -lで、確認できます。

注意点

  • nginxを使用していない場合、もちろん前半は不要です
  • unicorn_railsのフルパスはwhich unicorn_railsで確認できます
  • 環境によってunicorn_railsのフルパスが異なる場合もありますので、stagingで書いた設定を本番サーバーでコピペしないように気をつけてください
  • unicorn_railsをフルパスにしないと、
/bin/sh: unicorn_rails: command not found

というエラーが出て失敗すると思います。

これは、cron実行時のPATHのせいだそうです。cronでPATHを通す方法もあるようですが、設定するコマンドの量が多くなかったので今回はwhichでフルパスを調べて設定しました。

環境変数について

6/9 追記

cronの実行時、環境変数が足りずに色々なエラーが起きる可能性があるので、

rvm cron setup

を実行するとrvmがいい感じに設定してくれます

Google Dataportal(Datastudio)でMySQL8のRDSを使う方法メモ

※注意点

試行錯誤の結果色々変なことになっている箇所があるので、得た情報をつなぎ合わせたものを先に書いて、"動かなかった場合"として自分の環境も載せようと思います。

はじめに

google dataportalでは、MySQL8に対応していないらしく、そのままでは接続できませんでした。 公式のcommunityスレッドにとても有益な情報があったのでそれを参考にした結果接続できたのでそれを載せます。

引用元: https://support.google.com/datastudio/thread/4115506?hl=en&msgid=34547134

ざっくりまとめると、RDSに直接接続するのではなくProxySQLという色々よしなにやってくれるミドルウェアを間に挟むそうです!

前提

DB:RDS MySQL8.0.16 (色々試行錯誤したのでリードレプリカでpublicから接続できるDBを使っています。同じVPCの中に環境立てるのでpublicなDBでなくてもいけると思います。)

手順

1. ProxySQLの準備

EC2インスタンスの作成
  • AMI:Amazon Linux 2(他では試していません)
  • VPC:RDSと同じ
  • セキュリティグループ
    • port:22 ソース:myIP(proxysql設定の為)
    • port:6033 ソース:Google Dataportalのヘルプに書いてあるip一覧(カンマ区切り) 下記参照
64.18.0.0/20,64.233.160.0/19,66.102.0.0/20,66.249.80.0/20,72.14.192.0/18,74.125.0.0/16,108.177.8.0/21,173.194.0.0/16,207.126.144.0/20,209.85.128.0/17,216.58.192.0/19,216.239.32.0/19

引用元: MySQL に接続する - データポータルのヘルプ

ProxySQLの設定
  1. 上記で作成したEC2インスタンスssh接続
  2. ProxySQLのインストール

以下を実行

sudo vi /etc/yum.repos.d/proxysql.repo

以下を記入

[proxysql_repo]
name= ProxySQL YUM repository
baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.0.x/centos/\$releasever
gpgcheck=1
gpgkey=https://repo.proxysql.com/ProxySQL/repo_pub_key

以下を実行

sudo yum install proxysql

  1. proxysqlの設定

以下このファイルを触っていきます

sudo vi /etc/proxysql.cnf

~ 略 ~
admin_variables=
{
        admin_credentials="DBマスターユーザーパスワード or DBマスターユーザーパスワードをハッシュ化したもの"
#       mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
        mysql_ifaces="127.0.0.1" ←変更
#       refresh_interval=2000
#       debug=true
}
~ 略 ~

DBマスターユーザーパスワードのハッシュ化は、該当DBに接続し、

SELECT CONCAT("*", UPPER(SHA1(UNHEX(SHA1('DBマスターユーザーパスワード'))))) AS password;

上記のsqlを実行することで取得できるそうです。

~ 略 ~
mysql_variables=
{
        ~ 略 ~
        default_schema="DB名"
        stacksize=1048576
        server_version="8.0.16" ←変更
~ 略 ~

mysql_servers =
(
        {
                ~ ここから
                address = "RDSエンドポイント" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
                port = 3306           # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
                hostgroup = 0           # no default, required
                status = "ONLINE"     # default: ONLINE
                weight = 1            # default: 1
                compression = 0       # default: 0
                ここまでをコメントアウト~
#   max_replication_lag = 10  # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
        }, ←ここもコメントアウト
~ 略 ~

mysql_users:
(
        {
                username = "DBマスターユーザー名" # no default , required
                password = "DBマスターユーザーパスワード or DBマスターユーザーパスワードをハッシュ化したもの" # default: ''
                default_hostgroup = 0 # default: 0
                active = 1            # default: 1
        },
~ 略 ~

mysql_query_rules:
(
~ ここから
{
    rule_id=1
    active=1
    match_pattern="\@\@query_cache_size"
    replace_pattern="null"
    apply=0
},
{
    rule_id=2
    active=1
    match_pattern="\@\@query_cache_type"
    replace_pattern="null"
    apply=0
},
{
    rule_id=3
    active=1
    match_pattern="\@\@tx_isolation"
    replace_pattern="null"
    apply=0
},
ここまで 追加~
)
~ 略 ~
MySQLのインストール

※引用元には載っていませんでしたが、接続確認の為インストールしました。 不要かもしれません。

以下を実行

sudo yum -y install mysql mysql-devel

2. RDSの設定

セキュリティグループの設定

インバウンドルールに

port 3306 ソース:上記で作成したEC2のセキュリティグループ

を追加

3. ProxySQLの実行

以下を実行

sudo service proxysql start

4. Google Dataportal側での設定

新規レポート→データを追加→MySQL

  • ホスト名:上記で作成したProxySQLを実行しているEC2のパブリックIP
  • ポート:6033
  • データベース:接続したいDB
  • ユーザー名:DBマスターユーザー名
  • パスワード:DBマスターユーザーパスワード

を記入し 追加 をクリック

参考文献

ProxySQL公式 GitHub - sysown/proxysql: High-performance MySQL proxy with a GPL license.

Google Dataportal 公式スレッド https://support.google.com/datastudio/thread/4115506?hl=en&msgid=34547134

【Rails】booleanのカラムにenumを設定した際のチェックボックスの挙動

このようなmodelがあったとして、

class Billing < Activerecord
  
  enum billed: {
    done: true,
    in_progress: false
  } 

end

編集画面で

~略~
= f.check_box :billed
~略~

のようにすると一見編集できそうですが、このままだとチェックしてsubmitした際に

'1' is not is not a valid billed

のようなエラーが出ます。

色々調べたところenumの影響のようで、check_boxのデフォルトのチェック時の値が1なのでこのようになっているようです。 なので対策としてはcheck_boxのチェック時・非チェック時の値を変更すればokです。 今回の例では、

~略~
= f.check_box :billed, {}, checked_value='billed', unchecked_value='in_progress'
~略~

のようにすれば問題なく通ります。

【Rails】config/initializers内でDB接続が必要な処理を書いた際のCI対応

はじめに

今回、config/initializers内でDB接続を伴う設定をしたのですが、

  • assets:precompile
  • testDB作成

でエラーが出たのでその対応についてメモ。

前提

  • 使用DBはmysql8
  • assets:precompileはDockerfile内
  • CircleCIで、docker build、testDB作成などを行なっている

起きたことと対策

bundle exec rails assets:precompile実行時にMysql接続エラー

具体的には、

Mysql2::Error::ConnectionError: Unknown MySQL server host ~ 

このエラーでした。

プリコンパイルをする際、DB接続をしようとするらしいのですが、CIの際は実際のDBに接続できる訳ではないのでDB接続をしないようにする必要がありました。 そこで利用したのがactiverecord-nulldb-adapterというgemです。

ソースコードの変更・追加点は、

  • Gemfile
    • gem 'activerecord-nulldb-adapter' を追加
  • database.yml
    • adapter: mysql2adapter: <%= ENV['DB_ADAPTER'] ||= 'mysql2' %>に変更

こんな感じです。

testDB作成時にunknown databaseエラー

CIの途中、rspecを実行する前にその為のDBを作成する工程があるのですが、そこで

Mysql2::Error: Unknown databaseエラーが出ました。

db:createをする際、実際にDBを作成する処理より前にrailsの初期化が実行されている為、config/initializers内でDB接続している箇所でエラーが出ていたのです。 今回、rspecでは該当の処理を使わなかった為、設定ファイルのDB接続より前の箇所に、

return if Rails.env.test?を入れて対処しました。

rspecで該当箇所を使う場合は、returnではなくifで分岐して仮の値を入れるなどするといいような気がします。

【Rails】Ransackで年度を検索する方法

はじめに

Ransackには、カスタム述語という機能があり、複雑な検索条件を自分で作成することができます。

今回、年度を検索する必要があり、カスタム述語を使ってみましたので記憶に残すためにアウトプットしたいと思った次第です。

前提

  • 年度始まりは固定ではない
  • view側で指定するのは2019,2020などの数字

view側(slimです)

= f.select :●●_fiscal_year, 年度の配列, {:include_blank => true}

カスタム述語は、eqやcontのように、カラム名_述語名の形で使用します 年度の配列は、[2018,2019,2020]のように数字の配列になっています

config/initializers/ransack.rb

Ransack.configure do |config|
  term_start_date = ●● # 期始まりの日付取得
  # 年度検索
  config.add_predicate 'fiscal_year',
                       arel_predicate: 'between',
                       formatter: proc { |v|
                         term_start_date.change(year: v.to_i)..term_start_date.change(year: v.to_i).since(1.year).ago(1.day).to_date
                       },
                       type: :string # 検索条件として選択された値の型
end

以上になります。

参考文献:Ransackで簡単に検索フォームを作る73のレシピ - 猫Rails

RubyのCSV.foreachでうまく情報を取り出せない時に確認すること

RailsCSVからデータをインポートしようとして、Rubycsvクラスを使うことにしました。 一行ごとに取り出して操作をしたかったので、

CSV.foreach('csvファイルへのパス') do |row|
  処理
end

を使用しました。

1行ごとにrowに入るとのことだったので、てっきりrowには文字列型が入っているものだと思っていましたが、rowに対して

row.split(',')

としても思った動作になりませんでした。

実行して調べてみたところ、rowが既に配列であることがわかりました。 splitしなくとも、最初からrow[0]等で値が取れます。