- 投稿日:2020-08-09T23:15:55+09:00
[Rails]deviseを使ったウィザード形式での新規登録機能の実装
はじめに
フリマのコピーサイトを作る際に、構造をやや難しくしてしまったために苦労したので記録として残そうと思いました。もっと綺麗にかけるなどご指摘あればお願いします。
実装方法
開発環境
- Ruby 2.5.1
- Rails 5.0.7.2
- devise
前提
- deviseは導入済み
- deviseのデフォルト状態でのログイン機能は実装済み
- 1ページ目 → 2ページ目 → トップページ(ログイン)と遷移する
- テーブルは、
users
profiles
sending_destinations
の3つ- 1ページ目は1つのフォームで
Userモデル
とProfileモデル
の二つを扱っている
※2つのモデルに同時に値を送る方法はこちらの記事を参考にしています。
【Rails】deviseのフォームで2つのモデルに同時に値を送る方法(例: UserモデルとProfileモデル)DB設計
usersテーブル
Column Type Options name string null: false, unique: true, index:true string null: false, unique: true, index:true password string null: false profilesテーブル
Column Type Options first_name string null: false family_name string null: false first_name_kana string null: false family_name_kana string null: false introduction string null: true year integer null: false month integer null: false day integer null: false sending_destinations(住所)テーブル
Column Type Options first_name string null :false family_name string null: false first_name_kana string null: false family_name_kana string null: false post_code string null: false prefecture string null: false city string null:false house_number string null: false building_name string - phone_number string unique: true, null: true user_id references null: false, foreign_key: true コード
controllerの作成
- devise管理下の
users
コントローラーを作成するターミナル$ rails g devise:controllers users
- どのコントローラーを参照するのかルーティングを設定
routes.rbRails.application.routes.draw do devise_for :users, controllers: { registrations: 'users/registrations' } root to: 'items#index' endモデルにアソシエーションを記述する
User
、Profile
、Sending_destination
それぞれのモデルにアソシエーションを記述
※バリデーションは省略しています。user.rbclass User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_one :profile accepts_nested_attributes_for :profile has_one :sending_destination endprofile.rbclass Profile < ApplicationRecord belongs_to :user, optional: true endsending_destination.rbclass SendingDestination < ApplicationRecord belongs_to :user, optional: true end
optional: true
は外部キーがnullであることを許可するオプションです。newアクションと対応するビューを編集する(1ページ目)
- users/registrations_controller.rbにnewアクションを記述
users/registrations_controller.rbclass Users::RegistrationsController < Devise::RegistrationsController # 省略 def new @user = User.new @user.build_profile end # 省略 end
- newアクションに対応するregistrations/new.html.hamlを編集
devise/registrations/new.haml.html= form_for(@user, url: user_registration_path) do |f| = render "devise/shared/error_messages", resource: @user = f.text_field :nickname = f.email_field :email = f.password_field :password = f.password_field :password_confirmation = f.fields_for :profile do |p| = p.text_field :family_name = p.text_field :first_name = p.text_field :family_name_kana = p.text_field :first_name_kana = p.select :year = p.select :month = p.select :day = f.submit "次へ"実際はdivやlabel、classの記載がありますが、簡素に書いています。
2つのモデルを扱うためにfields_for
を利用しています。以下の記事を参考にしています。
【Rails】deviseのフォームで2つのモデルに同時に値を送る方法(例: UserモデルとProfileモデル)
【Rails】1つのform_forで複数モデルへデータ登録をする方法createアクションを編集
- 1ページ目で入力した情報のバリデーションチェック
- 1ページで入力した情報をsessionに保持させる
- 次の住所情報登録で使用するインスタンスを生成、当該ページへ遷移する 以上の3点がcreateアクションでやることになります。
users/registrations_controller.rbclass Users::RegistrationsController < Devise::RegistrationsController # 省略 def create @user = User.new(sign_up_params) @user.build_profile(sign_up_params[:profile_attributes]) unless @user.valid? flash.now[:alert] = @user.errors.full_messages render :new and return end session["devise.regist_data"] = {user: @user.attributes} session["devise.regist_data"][:user]["password"] = params[:user][:password] session[:profile_attributes] = sign_up_params[:profile_attributes] @sending_destination = @user.build_sending_destination render :new_sending_destination end # 省略 protected # 省略 end
valid?
メソッドでパラメータがバリデーションに違反しないかどうかチェックします。
ページが遷移しても情報が消えることが無いように、クライアント側で保持をさせておく機能session
を用いています。
sessionにハッシュオブジェクトの形で情報を保持させるために、attributesメソッドを用いてデータを整形しています。また、paramsの中にはパスワードの情報は含まれていますが、attributesメソッドでデータ整形をした際にパスワードの情報は含まれていません。そこで、パスワードを再度sessionに代入する必要があります。
build_sending_destination
で今回生成したインスタンス@user
に紐づくsending_destination
モデルのインスタンスを生成します。
そして、住所情報を登録させるページを表示するnew_sending_destination
アクションのビューへrenderします。new_sending_destinationアクションと対応するビューを編集する(2ページ目)
- 住所登録をするページを表示する
new_sending_destination
アクションのルーティングの設定- 住所を登録する
create_sending_destination
アクションのルーティングの設定routes.rbRails.application.routes.draw do devise_for :users, controllers: { registrations: 'users/registrations' } devise_scope :user do get 'sending_destinations', to: 'users/registrations#new_sending_destination' post 'sending_destinations', to: 'users/registrations#create_sending_destination' end root to: 'items#index' end
- 該当するビューファイルであるnew_sending_destination.html.hamlを作成
devise/registrations/new_sending_destination.html.haml= form_for @sending_destination do |f| = render "devise/shared/error_messages", resource: @sending_destination = f.text_field :family_name = f.text_field :first_name = f.text_field :family_name_kana = f.text_field :first_name_kana = f.text_field :post_code = f.text_field :prefecture = f.text_field :city = f.text_field :house_number = f.text_field :building_name = f.number_field :phone_number = f.submit "登録する"create_sending_destinationアクションを編集する
- 2ページ目で入力した住所情報のバリデーションチェック
- バリデーションチェックが完了した情報と、sessionで保持していた情報とあわせ、ユーザー情報として保存する
- sessionを削除する
- ログインをする
users/registrations_controller.rbclass Users::RegistrationsController < Devise::RegistrationsController # 省略 def create_sending_destination @user = User.new(session["devise.regist_data"]["user"]) @profile = @user.build_profile(session[:profile_attributes]) @sending_destination = SendingDestination.new(sending_destination_params) unless @sending_destination.valid? flash.now[:alert] = @sending_destination.errors.full_messages render :new_sending_destination and return end @user.build_sending_destination(@sending_destination.attributes) @user.save @profile.save session["devise.regist_data"]["user"].clear session[:profile_attributes].clear sign_in(:user, @user) redirect_to root_path end protected def sending_destination_params params.require(:sending_destination).permit( :first_name, :family_name, :first_name_kana, :family_name_kana, :post_code, :prefecture, :city, :house_number, :building_name, :phone_number ) end end
@user
と@prfile
それぞれのインスタンスにsessionで保持した情報を代入しています。
2ページ目の住所情報をvalid?
でチェックします。
build_sending_destinationを用いて送られてきたparamsを、保持していたsessionが含まれる@user
に代入します。そしてsave
メソッドを用いてテーブルに保存します。
clear
メソッドを用いてsessionを削除します。
sign_in(:user, @user)
でログインし、redirect_to root_path
でトップページに遷移します。おわりに
以上の方法で実装できます。1ページ目で
fields_for
を用いたことでsessionへの代入にかなり四苦八苦しましたが、おかげでしっかり仕組みなどを考えることができました。細かな説明はしていませんが、アウトプットも兼ねて記事にしてみたので少しでも参考になれば幸いです。
- 投稿日:2020-08-09T22:53:45+09:00
〇〇/〇〇.rb:1: Invalid char `\x08' in expression が出てきたけど、速攻で解決した。
本題
Rubyを再学習してる時に、謎のエラーが出てきた。
見たこともないエラーなので良く調べたが、一瞬で解決・・・解決方法
該当の行をもう一度打ち直そう!!
内容
エラー分を翻訳してみると・・・
test/gate_test.rb:1: Invalid char \x08' in expression
→式に無効な文字 \ x08 'があります・
・
・?
といったところで勘付きました。また誤字しているんだなと。
そんでもって、該当行を書き直したところ・・・エラーは出なくなりました。
他の方のサイトを拝見させていただいたところ、不可視文字が原因のようです。
このエラーについては、速攻で打ち直すのが吉ですね。参考にさせていただいたサイト
https://tattaka-s.hatenablog.com/entry/2019/07/06/153703
かな〜り詳しく書いていただいているので気になる方はご覧ください??♂️
- 投稿日:2020-08-09T22:35:41+09:00
Kinx Tips - 実行形式ファイルを作る
Kinx Tips - 実行形式ファイルを作る
はじめに
「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。今回は Tips です。
- 参考
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
- 個別記事へのリンクは全てここに集約してあります。
- リポジトリ ... https://github.com/Kray-G/kinx
- Pull Request 等お待ちしております。
皆さん、実行ファイルを作る時どうしてますか? ...そう、普通は C や C++ で書いてコンパイルしますね。もっと簡単に作れるといいですね。
Kinx は独立した exe を作ることはサポートしていませんが、Kinx のワールドの中であれば exe にして単体実行コマンドのように見せかけて実行できるモジュールを作れるようにしています。
その辺を少々。
コマンド
kxrepl.exe
、kxtest.exe
実は v0.13.1 リリースより
kxrepl.exe
とkxtest.exe
というコマンドが同梱されています。Linux 版では.exe
はついて無くてkxrepl
とkxtest
です。
kxrepl
を実行してみましょう。$ kxrepl kinx[ 0]> .quitREPL が動作しましたね。
次は
kxtest
です。$ kxtest -v -T declaration.md Test Cout = 11 Entry: doc/spec/statement/declaration.md Suite: Declaration statement Case[ 0]: Normal case ................................... successful ( 0.10s) Case[ 1]: With initializer .............................. successful ( 0.09s) Case[ 2]: With initializer of expression ................ successful ( 0.09s) Case[ 3]: Multiple variable declaration ................. successful ( 0.10s) Case[ 4]: Constant value (1) ............................ successful ( 0.07s) Case[ 5]: Constant value (2) ............................ successful ( 0.10s) Case[ 6]: Constant value (3) ............................ successful ( 0.07s) Case[ 7]: Constant value (4) ............................ successful ( 0.07s) Case[ 8]: Constant value (5) ............................ successful ( 0.09s) Case[ 9]: Destructuring assignment (1) .................. successful ( 0.09s) Case[10]: Destructuring assignment (2) .................. successful ( 0.07s) <Test Result> Total Test Cases: 11 Successful : 11 Failed : 0 Warning : 0SpecTest が動作しましたね。
もう一つ、試しにやってみましょう。
$ diff -s kxrepl kxtest Files kxrepl and kxtest are identical「ファイルは同一です」 というメッセージがでました。というか、そうなんです。この 2 つは バイナリとして全く同じ です。
--exec
オプションの話この話の前に、一つ Kinx のオプションに関する情報を書いておきます。
--exec
というオプションです。README にも書いてある通り、このオプションによって以下の 2 つのオプションがサポートされています。
--exec:repl
... REPL を実行する。--exec:specttest
... SpecTest を実行する。このメカニズムは、以下の通りになっています。
--exec:xxx
を認識したら、Kinx の実行ファイルのあるフォルダから見てlib/exec/xxx.kx
、またはlib/exec/3rdparty/xxx.kx
を探す。- そのファイルがあったら、そのファイルがスクリプトファイルとして指定されたとみなして実行する。
なので、REPL と SpecTest はそれぞれ
lib/exec/repl.kx
とlib/exec/spectest.kx
ファイルを探してそれを実行する、という動作をしているのです。この仕組みによって、REPL と SpecTest の修正はバイナリを修正せずに実施できるようにもなっています。kxrepl
さて、kxrepl のバイナリ(= kxtest のバイナリ)ですが、どういう作りになっているのでしょう(概ね見当は付くと思いますが)。答えはこうです。
- 自分自身の実行ファイル名(
name
としましょう)を取得(argv[0]
から取得できます)。- コマンドライン引数の先頭に
--exec:name
を割り込ませて引数リストを更新。- Kinx のメインロジックに制御を渡す。
するとどうでしょう。自動的に
lib/exec/name.kx
(またはlib/exec/3rdparty/name.kx
)を参照して実行してくれるのです!ということで、
kxrepl
はlib/exec/kxrepl.kx
を、kxtest
はlib/exec/kxtest.kx
を自動的に実行してくれるという寸法です。ん?、そんなファイルあったっけ?はい、追加したんです(=あります)。中身を見てみましょう。
lib/exec/kxrepl.kxusing exec.repl;lib/exec/kxtest.kxusing exec.spectest;これだけです。中で
using
するだけのファイルを用意して実現しました。using
の検索パスに従ってrepl.kx
とspectest.kx
を見つけてくれるので、これで正しく動作します。というわけで、kxrepl.exe
をrepl.exe
に書き換えても同様に動きます。ということで、もうお分かりですね。
オリジナル
exe
を作ろうオリジナル
exe
ファイルの作り方は以下の通りです。動作には Kinx の dll と各種ライブラリが必要なので、kinx.exe
と同じ場所に、作成したexe
を置かなくてはなりませんが、やりたいことをコマンド一発でできるようにはなります。具体的な例で。
kxcat.exe
cat
コマンドみたいなものとして、kxcat
コマンドを作ってみましょう。指定されたファイルを指定された順に出力します。cat
コマンドと名前が重ならないようにkxcat
にしておきましょう。一先ずオプションは無しで、ファイルだけ複数受け付けるようにします。lib/exec/3rdparty/kxcat.kx$$.each { // Ignoring the script file name. if (_2 > 0) { System.print(File.load(_1)); } };さて、そうしたら
kxtest.exe
をコピーして名前を変えましょう。Windows でも Linux でもコマンドは違いますが、やりたいことは同じです。Windows$ copy /y kxtest.exe kxcat.exeLinux$ cp -f kxtest kxcatコピーしたらそのまま
kxcat
コマンドを実行!$ ./kxcat README.md ChangeLog.md <p align="right"> <img src="https://github.com/Kray-G/kinx/workflows/Unit%20Test/badge.svg?branch=master"/> <img src="http://img.shields.io/badge/license-MIT-blue.svg?style=flat"/> </p> ...(省略) ## V0.1.0 (1st Preview Release) * Initial Release.できましたね。
インストールされたもので実行したい場合、Linux では以下の場所に
kinx
コマンドのバイナリがあるので、例えば上記の場合、kxcat
コマンドは同じ位置に配置してください。kxrepl
、kxtest
も同じ場所に配置してあります。$ which kinx kxrepl kxtest /usr/bin/kinx /usr/bin/kxrepl /usr/bin/kxtestおわりに
C でがっつり書いてコンパイルして実行ファイルを作る、でもいいんですけど、スクリプトでササっと書いたのを実行形式ファイルにしたいですよね。かといって、必要なライブラリとか dll とかを全部含めると結構なサイズになったりするので、ここは割り切って Kinx 自体が存在する前提でコマンド化できるようにしてみました。
これはこれで便利かなー、と思います。
あと、やればすぐできるんですけど、例えば kinx.dll の位置を環境変数で指定したり、オプションで渡したりできると、
.exe
ファイル自体はどこにおいても良くなるのでそのくらいの対応は今後するかも入れません(要望があれば)。xxx.exe
と同じ場所にあるxxx.kx
を実行するとかね。そのほうが便利かなー。dll
の場所は何かしらの方法で指定しておく必要はありますが。ではでは、また次回。
- 投稿日:2020-08-09T22:30:17+09:00
MinGWにプルリクエストを送ってlibgrのバージョンをアップデートした話
はじめに
こんにちは。MinGWのパッケージをアップデートしたので記事にします。
どうしてMinGWのパッケージのアップデートしなきゃならないの?
パッケージマネージャーって、みんな利用していると思うんですけど、そのメンテナンスに関わったことがある人は意外と少ないと思います。私もMinGWのパッケージをアップデートするのははじめてです。
1年程前から趣味と実益を兼ねてRuby向けのグラフ描出ソフトGR.rbを作っています。
GR.rbは
libgr
のバインディングです。私は普段Windowsを使っていません。しかし、ありがたいことに是非Windowsに対応してほしいという要望があって、詳しい方にPKGBUILDの作成からMinGWにlibgrのパッケージ登録まで全部やって頂きました。それから少し時間が流れて、本家libgrのバージョンも少しずつ上がっていくので、そろそろアップデートしないといけないなと思い、重い腰を上げて 0.50.0 → 0.51.2 にアップデートしました。
MingGWのパッケージのアップデート、結果的には難しくなかったのですが、MinGWのパッケージをアップデートした日本語の体験記事が全然なくてとても心細い思いをしました。誰かの役に立つようにQiita記事を書きます。
やり方
基本的な方法はhomebrewなどと変わりません。
MSYS2公式ページ
https://www.msys2.org/wiki/Creating-Packages/に必要な情報が載っていますので、Google翻訳などを使ってざっと目を通すと良いと思われます。
git clone
git clone https://github.com/Alexpux/MINGW-packages cd MINGW-packages/mingw-w64-grあとから
origin
を変更してもいいのですが、最初からForkしてしまった方が作業が楽ですね。git clone https://github.com/YOURNAME/MINGW-packages cd MINGW-packages/mingw-w64-grPKGBUILDの編集
パッケージのバージョン番号を更新します。
PKGBUILDpkgver=0.51.2sha256sumを更新します
PKGBUILDsha256sums=("E6A3D0ED911F6E59CC2293B5694EE18A0620849E666143870A9EDA71C02BB833")また、今回は、前回適応されていたパッチが不要のようだったので取り除きました。
ビルドとインストール
makepkg-mingw -sCLf pacman -U mingw-w64-*-gr-*-any.pkg.tar.xzでできます。
プルリクエストを送る
大丈夫そうだったらブランチを切ってプルリクエストを送りましょう。
忘れずにgit pull --rebaseブランチの名前はなんでも良さそうですが、
gr-0.51.2
としました。
プルリクエストのコミットは、皆さん大文字、小文字が入り乱れていますが、gr: Update to 0.51.2
もしくはgr: update to 0.51.2
とすればよいようです。プルリクエストを提出したら、ちゃんとCIが通過しているか確認しましょう。
通過していればメンテナンスをされている方がチェックしてマージしてくれるはずです。今回のPRは数時間のうちに無事にmergeされました。かなり活発にメンテナンスが行われているようです。
おわりに
MinGWもバージョンをアップデートするだけなら怖くない!
この記事は以上です。
- 投稿日:2020-08-09T21:08:11+09:00
Rails reference型 作成 追加
はじめに
今回はrailsでのマイグレーション時にreference型を扱うことがことがあったのでまとめる。
外部キーとは
reference型を扱うにあたって外部キーについて知っておかなくてはならない。
外部キーとは、リレーショナルデータベース(RDB)で、テーブルのある列に、別のテーブルの特定の列に含まれる項目しか入力できないようにする制約。また、その際に指定する列
http://e-words.jp/w/%E5%A4%96%E9%83%A8%E3%82%AD%E3%83%BC.html#:~:text=%E5%A4%96%E9%83%A8%E3%82%AD%E3%83%BC%E3%81%A8%E3%81%AF%E3%80%81%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB,%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E8%A8%AD%E5%AE%9A%E3%81%A7%E3%81%8D%E3%82%8B%E3%80%82今回はarticlesテーブルにreference型のuser_idという外部キーを設定する。
前提
sampleとしてuserテーブルとariticleテーブルを準備する。
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.string :name t.string :email end end endclass CreateArticles < ActiveRecord::Migration[6.0] def change create_table :articles do |t| t.string :title t.string :content end end end$ rake db:migratereference型のカラムの作成
reference型で作成すると
user
そのまま追加されるわけではなくuser_id
というカラム名で追加される。また、index:true
を追記することなく自動でインデックスをはってくれるというメリットもある。class CreateArticles < ActiveRecord::Migration[6.0] def change create_table :articles do |t| t.string :title t.string :content t.references :user, foreign_key: true end end end*
foreign_key: true
をつけないと外部キー制約はつけることができない。
foreign_key: true
を書き忘れたことで設定できないこtがあった。
add_foreign_key
を使っての追加も可能。class CreateArticles < ActiveRecord::Migration[6.0] def change create_table :articles do |t| t.string :title t.string :content end add_foreign_key :articles, :users end endreference型のカラムの追加
class AddReferenceColumn < ActiveRecord::Migration[6.0] def change add_reference :articles, :user, foreign_key: true end endこの際にも
foreign_key: true
を忘れずに。
- 投稿日:2020-08-09T19:01:27+09:00
Ruby テキスト変換
Ruby を使って PHP のプログラムを変換します。
PHPの文字コードは、EUC_JP と CP51932 が混在しています。
Python は、CP51932 を取り扱えないので、Ruby で記述しました。str_src を str_target に置き換えます。
str_src がない時は、何もしません。file_filter.rb#! /usr/bin/ruby # -*- coding: utf-8 -*- # # file_filter.rb # # Aug/09/2020 # # # -------------------------------------------------------------------- # [2]: def read_proc(file_in) lines = [] File.open(file_in) do |io| lines = io.readlines() end # return lines end # # -------------------------------------------------------------------- # [4]: def convert_proc(lines) flag_convert = false str_src = '$var = $dict["aa"];' str_target = 'if(array_key_exists("aa",$dict)){$var = $dict["aa"];}' llx = str_src.size lines_new = [] for line in lines do if line.slice(0,llx) == str_src then puts line lines_new.push(str_target) flag_convert = true else lines_new.push(line) end # end # return flag_convert,lines_new end # -------------------------------------------------------------------- # [6]: def out_proc(file_out,lines_new) File.open(file_out, mode = "w") do |f| lines_new.each{ |line| f.puts(line)} end STDERR.puts file_out + " written ***" end # -------------------------------------------------------------------- STDERR.puts "*** start ***" file_in = ARGV[0] # lines = read_proc(file_in) # flag_convert,lines_new = convert_proc(lines) # if flag_convert then out_proc(file_in,lines_new) end # STDERR.puts "*** end ***" # --------------------------------------------------------------------実行
./file_filter.rb in01.txt
- 投稿日:2020-08-09T18:13:00+09:00
コンテナ上のデバッグ環境構築 - DockerでRailsチュートリアルのローカル開発環境構築 -
はじめに
Dockerでローカル開発環境構築を行い、Railsチュートリアルを再走しております
- Railsチュートリアル最新版(2020.8.6現在)に対応のRails 6
- Dockerを使用し、開発環境の再現が可能
- なるべくローカル環境にインストールしない
今回はRailsチュートリアルの7章に相当する部分で、
Dockerコンテナ上で開発を行っている場合にデバッグを行う内容を紹介します第一回
DockerでRailsチュートリアルのローカル開発環境構築(Rails 6 + PostgreSQL + Webpack) - Qiita第二回
DockerでRailsチュートリアルのローカル開発環境構築 - RSpec導入 & CircleCIでHerokuデプロイ- - Qiita第3回
DockerでRailsチュートリアルのローカル開発環境構築 - WebpackでBootstrapとFont Awesomeを導入 - - Qiita個人開発アプリ
mdClip <オンラインmarkdownエディタ>Dockerのコンテナ上で操作する場合はターミナルのコマンドを適宜
$ docker-compose run app ...もしくは
$ docker-compose exec app ...で置き換えてください。
Dockerコンテナ上の開発環境でRailsのデバッグを行う
方法1 Railsのコンテナにアタッチ -> デタッチ
参考サイト
Docker と Rails 5.2 の開発環境でデバッグを行えるようにする - ココナラよもやまブログRailsのコンテナにアタッチする
$ docker attach $(docker-compose ps -q app)これでデバッグコンソールが使用できます
コンテナからデタッチする
デバッグを
quit
で抜けると
コンテナが終了してしまうのでrails server
も落ちる
これではすごく使い勝手が悪いなと思ったらコンテナからデタッチ(
Control P
->Control Q
)するだけなら、コンテナを終了しなくて済むとのことただ、VS Codeのコンソールで操作していると
Control P
,Control Q
は他のショートカットに割り当てられないこれはコンテナでタッチキーを置き換えることで解決方法とのことです
参考記事
docker で Ctrl-p 2回押し問題 (detach-keys の問題) を解決するには - Qiita
~/.docker/config.json
に設定を記述しますvi ~/.docker/config.json{ # ...省略 "detachKeys": "ctrl-e" }私は
control + e
でデタッチできるように設定しました方法2 VS Codeでデバッグ用のコンテナを動かす
VS codeのデバッグ機能から、デバッグ用のコンテナを立ててデバッグする方法もあるようです
Developing inside a Container using Visual Studio Code Remote Development
シームレスで便利そうだと思ったのですが
ここまででちょっと時間を使ってしまったのでまた別の機会に追記します自分用メモ
Get started with development Containers in Visual Studio Code
[VS Code - Remote Containers で Docker Compose で動いている Rails アプリに接続する - さめたコーヒー](
- 投稿日:2020-08-09T15:29:47+09:00
テクトロジーによる実践的組織構造学
今回の記事では、ソ連の革命家、医師、哲学者、小説作家であったアレクサンダーボグダノフが提唱したテクトロジーと呼ばれる実践的組織構造学について紹介する。
テクトロジーでは組織が安定、成長、破綻する環境、条件について詳細に解説し、安定した組織を生成する手法について解説している。
テクトロジーの概念を拝借し、創造的な組織創造の手法を紹介したいと思う。テクトロジーにおける組織の定義
テクトロジーでは、組織をオープンクローズ型の成長する有機体システムと定義している。
組織とは以下の要素で構成されている。
ビジョン・・・組織の目指すべき方向性。
経済・・・組織のボディ。巨大であるほど収容できる人の人数が増加する
金融・・・組織を循環する血液。
生産・・・もの、サービスを生産し、組織の経済を巨大化する手段。これらの有機的な要素が相互作用し、成長することで組織という有機体が構成されていると考える。
テクトロジーにおける成長する有機体システムとは
テクトロジーでは、組織をオープンクローズ型の成長する有機体システムと定義している。
テクトロジーにおける組織の定義を中国の陰陽論によって説明することができる。
陰陽論とは、原初は混沌(カオス)の状態であると考え、この混沌の中から光に満ちた明るい澄んだ気、すなわち陽の気が上昇して天となり、重く濁った暗黒の気、すなわち陰の気が下降して地となった。この二気の働きによって万物の事象を理解し、また将来までも予測しようというのが陰陽思想である。
組織が外部からエネルギーを取り入れ、出力するインプット、アウトプットの運動を陰陽論における陽の気と捉えることができる。
逆に組織内部に沈殿し、成長し、ヒエラルキーを形成する秩序生成を担う運動を陰陽論における陰の気と捉えることができる。テクトロジーにおける生産の定義
テクトロジーでは、組織における生産活動は以下の3つに分類されている。
人の生産・・・人に教育を施し、組織活動に従事する生産者を作成する
モノ、サービスの生産・・・外部から取得した資材を用いて、モノ、サービスの生産を行う。
アイデア・・モノ、サービスを生成するための知識、アイディアを作成する。
組織における生産活動を高めることで、組織の経済を成長させることができる。テクトロジーおける組織のフォーム(形態)について
現実の世界で、人が活動を行う場合、必ず外部からの影響、抵抗を受ける。
外部からの影響、抵抗を抑えるために、組織は環境に合わせた最適なフォーム(形態)を取る必要がある。
魚やイルカなど、魚と哺乳類で種族は異なるが、水の抵抗を抑えるために同様の流線形フォルムを取っている。
組織のフォーム(形態)は外部環境によって決定される。
外部環境からの抵抗を最小限にするために、外部との接触の最小化、不要な組織的機能の削除などが求められる。
最適なフォーム(形態)によって、組織は外部からの抵抗を減少させ、健全に成長することができる。テクトロジーにおける組織が不安定化する条件
テクトロジーにおける組織が不安定化する条件として以下の2点が挙げられる。
・外部からのエネルギー取得の減少・・外部から人、モノ、金の循環が減少することで組織のサイズ、経済を維持することできなくなる。
・ヒエラルキーシステムの固定化・・・ヒエラルキーシステムが巨大化し、組織が硬直化してしまう。
組織不安定化を回避する手法として以下の手段が有効とされている。
生産手段を研究、開発、更新を行い、組織の経済成長のスピードを増加させる。
組織が硬直化の原因になっているヒエラルキーシステムを解体し、適切なサイズに組み替える。まとめ
アレクサンダーボグダノフがテクトロジーに関するアイディアを発表した時期は1920年代である。
独学で組織が破綻する条件、環境を発見し、持続可能な成長のコンセプトを提唱したアレクサンダーボグダノフの先見性は恐るべきものである。
ソ連は軍事、IT、経済においてアメリカと張り合うことができた超大国だった。
ソ連時代に考えられたアイディア、思想などは現代においても見直されるべきものだと思われる。
- 投稿日:2020-08-09T15:29:19+09:00
リファクタリングしてみた①
バージョン
・ruby 2.5.7
・Rails 5.2.4.3ポートフォリオのコードをリファクタリング
まず、現状はというと下記の通り。ひどい、、。ほぼ同じ事を書いているアクション名が8つ存在している。まず、そのdate1からdate8のアクションをリファクタリングしてみる。
それぞれの処理で分ける処理は何か?同じ処理は何か?の視点で考える
まずこのdate1からdate8のアクションの処理内容を大まかに分類すると、
date1は新しくレコードをnewする処理。
date2からdate7は新しくレコードをnewする処理+前のページから渡ってきたカラムを受け取って、レコードを保存する処理。
date8は前のページから渡ってきたカラムを受け取って、レコードを保存する処理+また別のレコードを保存する処理。
なので、date2〜date7はまとめれそうだと考えた。同じ処理をまとめるにはどうしたらいいか
今回の場合、リファクタリングしたくてもそれを阻んでいたのはこのpageカラムの存在。
date2~7はpageの値が変わっているだけで、後の処理はredirect先が違うくらいでコードは一緒だった。
ページ遷移するごとに値を増やしていく
pageの値を自分で書くのではなく、ページが変わるごとに値が+1ずつされるようにコードかけばいいのではと考えた。
その為にまずdate1で@conto_page = 1とインスタンス変数を作る。
次に、ビュー側で値を受取り、form_withでconto_page: @conto_pageでdate2に@conto_pageを渡す。
最後に、受け取ったparams[:conto_page].to_i == 8 ならdate8に行くようにredirectして、それ以外ならconto_pageが+1ずつ増えて行く処理をして
リファクタリング完成!
無事にdate3~date7のアクションは消す事が出来ました。
さっきよりコード量が4割ほど削減が出来ました。
- 投稿日:2020-08-09T15:08:15+09:00
【クエリ爆減】update_allで一定条件下の複数データをまとめて更新する【Ruby on Rails】
入荷から一定期間経過した商品には割引(30日以上→500円・60日以上→1000円・90日以上→1500円)を適用する為、以下の様なロジックを書きました。
items = Item.where("created_at < ?", Time.zone.now - 30.days) items.each do |item| created_at = item.created_at today = Time.zone.today three_month = 90.days two_month = 60.days one_month = 30.days if today >= created_at + three_month discount = -1500 elsif today >= created_at + two_month && today < created_at + three_month discount = -1000 elsif today >= created_at + one_month && today < created_at + two_month discount = -500 end item.discount = discount item.save endしかし上記のコードでは、
items
の数の分処理が走ってしまう所謂 N+1問題 が発生し、処理速度やメモリに大きな影響を与えてしまいます。そこで活躍するのが
update_all
。
以下の様に条件をhash
に纏めて配列に格納、各条件に当てはまるデータを纏めて更新します。today = Time.zone.now conditions = [ { upper_limit: today - 30.days, lower_limit: today - 59.days, amount: -500 }, { upper_limit: today - 60.days, lower_limit: today - 89.days, amount: -1000 }, { upper_limit: today - 90.days, lower_limit: today - 365.years, amount: -1500 }, ] conditions.each do |condition| Item. where("created_at between ? and ?", condition[:lower_limit], condition[:upper_limit]). update_all(discount: condition[:amount]) endするとクエリは条件分のたった3つだけに収まります?
Item Update All (8.8ms) UPDATE `items` SET `items`.`discount` = -500 WHERE (created_at between '2020-04-27 00:00:00' and '2020-05-26 00:00:00') Item Update All (3.2ms) UPDATE `items` SET `items`.`discount` = -1000 WHERE (created_at between '2020-03-28 00:00:00' and '2020-04-26 00:00:00') Item Update All (19.4ms) UPDATE `items` SET `items`.`discount` = -1500 WHERE (created_at between '1920-06-25 00:00:00' and '2020-03-27 00:00:00')※ActiveRecordオブジェクトを経由しない更新方法のため、バリデーションやコールバックは実行されない点にご注意ください。
- 投稿日:2020-08-09T09:53:22+09:00
Railsでのカラムの追加
カラムの追加
新しいカラムの追加(基本)
$rails g migration (行う処理+テーブル名)(追加したいカラムとデータ型など)
$rails g migration AddColumnToUsers name:string age:integer
新しいカラムにインデックスを追加
$rails g migration AddColumnToUsers name:string:index
カラムの削除
$rails g migration RemoveNameFromUsers name:string
テーブルの作成と同時にカラムの作成
$rails g migration CreateUsers name:string age:integer
- 投稿日:2020-08-09T03:38:51+09:00
Mac ruby 2.0.0におけるDEFAULT_CERT_FILEのディレクトリ情報
過去記事でopenssl、curl、rubyをソースビルド、インストールしたMacとは別のMacがある。
MacOSX 10.11はhomebrewが動作するが削除し概ねクリーンにした。ruby 2.0.0に戻る。すると
$ ruby -ropenssl -e "p OpenSSL::X509::DEFAULT_CERT_FILE"
"/System/Library/OpenSSL/cert.pem"OpenSSL $ ls -la
total 8
drwxr-xr-x 6 root wheel 204B 2 5 2016 .
drwxr-xr-x 82 root wheel 2.7K 8 28 2018 ..
drwxr-xr-x 2 root wheel 68B 2 5 2016 certs
drwxr-xr-x 8 root wheel 272B 2 5 2016 misc
-rw-r--r-- 1 root wheel 9.2K 2 5 2016 openssl.cnf
drwxr-xr-x 2 root wheel 68B 2 5 2016 private
OpenSSL $ cd certs
certs $ ls -la
total 0
drwxr-xr-x 2 root wheel 68B 2 5 2016 .
drwxr-xr-x 6 root wheel 204B 2 5 2016 ..
certs $以上、メモ書き。
- 投稿日:2020-08-09T02:56:40+09:00
openssl、curl、rubyインストールについての印象や覚え
●備忘録 メモ書き 証拠のログは殆ど無し
2020年08月上旬にautoconfからopenssl、curl、rubyまでソースインストール出来た。
openssl curl(wget)Ruby等々のSSL通信に悩まされてきたが殆ど解消したかもしれない。kindai.rbを使い始めた時期(2015〜2017?)は記憶にない。
qiitaでの質問は2017年が最初。(他に5chで質問したかも?)2020年07月までに行ったopenssl curl(wget)Ruby等の環境構築でログが残ってないが、覚えていることを書いておく。●事象
homebrewのImageMagick インストールをみていると大量のコマンドとライブラリがインストールされる。依存関係もあるらしく自分ではソースビルドが出来ないと考えていた。
ー>実際は簡単だった。手間と時間がかかるだけ。homebrewはリンク切れや不具合を起こす。数年に一回程度。homebrewの再インストールの経験が「たしか3,4回数/一台のMac」ある。
openssl又はcurlインストールにおいて、homebrewビルドでもソースビルドでもSSL通信の不具合が起きた。バージョンアップだけでも起きた。
証拠のログがない。
ー>homebrewビルドのほうが成功率は高かった。rbenvインストールにおいて、homebrewビルドでもソースビルドでも不具合が起きた。
証拠のログが一部ある。
今回(08月上旬)も問題が起きた。
ー>不具合が嫌でstowで管理した。
ー>sotwではリンク変更とパス変更、source bash_profile やsource .zshrcが必要なのでやや手間だが、stow管理の方がopensslやcurl連携しSSL通信出来るようになるまで短時間で済む気がする。●印象や覚え
rbenvがするrubyインストールにおいて、./configureオプションはネット上であまり検証されてないように思う。
homebrewがするrubyインストールにおいて、./configureオプションはネット上で検証されてないように思う
homebrewがするcurlインストールにおいて、./configureオプションはネット上で検証されてないように思う
homebrewがするopensslインストールにおいて、./configureオプションはネット上で検証されてないように思う全てソースビルドされた場合。
openssl作者の意図(./configureオプション)
curl作者の意図
ruby作者の意図だけならともかく、加えてhomebrewの理解と意図がある場合。
homebrew作者が上記の意図を理解した(かもしれないので間違いがあるかも?)上での
opensslの./configureオプション
curlの./configureオプション
rubyの./configureオプション
(rbenv、ruby-buildなし)
最も問題が少なそう?さらに加えて、rbenv(ruby-build)ビルドされた場合。
rbenv(ruby-build)作者が意図する
opensslの./configureオプション理解(インスト済みの環境を把握する)
curlの./configureオプション(インスト済みの環境を把握する)
rubyの./configureオプションさらに場合分けで、全てhomebrewビルドされた場合。
rbenv(ruby-build)の意図する
opensslの./configureオプション理解(インスト済みの環境を把握する)
curlの./configureオプション(インスト済みの環境を把握する)
rubyの./configureオプション
この場合だけは二番目に問題が少なそうではあるが、疑問が残った結果だ。ツールが多ければ問題の切り分けが難しいのは分かってもらえると思う。
一番下の全てhomebrewに任せる場合も不具合がある。
組み合わせはともかく、kindai.rb動作に至るまでにSSL関連の失敗、不具合(不明瞭?)今までopenssl、curl、rubyのインストールを何度やり直したか分からない。インストール(configureオプション)と使い方で
opensslの質問
curlの質問
rubyの質問
等々、それぞれがネットに大量にある状態だ。(ありすぎて問題だ。)数年間、筆者はqitta以外でもインストール記事を読んできたが、今まで上記の点を指摘か注意した記事を一つも見当たらなかった。(linuxでなくMacだからかもしれないが。)
今回で筆者はソースビルドが一番早いと考えを改めるようになった。
記憶と推測だけで申し訳ない。
過去のインストールログが残っておらず突っ込み所は多数があるが、ご容赦を。以上
- 投稿日:2020-08-09T02:56:40+09:00
openssl、curl、ruby、homebrew、rbenvインストールについての印象や覚え
●備忘録 メモ書き 証拠のログは殆ど無し
2020年08月上旬にautoconfからopenssl、curl、rubyまでソースインストール出来た。
openssl curl(wget)Ruby等々のSSL通信に悩まされてきたが殆ど解消したかもしれない。kindai.rbを使い始めた時期(2015〜2017?)は記憶にない。
qiitaでの質問は2017年が最初。(他に5chで質問したかも?)2020年07月までに行ったopenssl curl(wget)Ruby等の環境構築でログが全て残ってないが、覚えていることを書いておく。●事象
homebrewのImageMagick インストールをみていると大量のコマンドとライブラリがインストールされる。依存関係もあるらしく自分ではソースビルドが出来ないと考えていた。
ー>実際は簡単だった。手間と時間がかかるだけ。homebrewはリンク切れや不具合を起こす。数年に一回程度。homebrewの再インストールの経験が「たしか3,4回数/一台のMac」ある。
openssl又はcurlインストールにおいて、homebrewビルドでもソースビルドでもSSL通信の不具合が起きた。バージョンアップだけでも起きた。
証拠のログがない。
ー>homebrewビルドのほうが成功率は高かった。rbenvインストールにおいて、homebrewビルドでもソースビルドでも不具合が起きた。
証拠のログが一部ある。
今回(08月上旬)も問題が起きた。
ー>不具合が嫌でstowで管理した。
ー>stowではリンク変更とパス変更、source bash_profile やsource .zshrcが必要なのでやや手間だが、stow管理の方がopensslやcurl連携しSSL通信出来るようになるまで短時間で済む気がする。●印象や覚え
rbenvがするrubyインストールにおいて、./configureオプションはネット上であまり検証されてないように思う。
homebrewがするrubyインストールにおいて、./configureオプションはネット上で検証されてないように思う
homebrewがするcurlインストールにおいて、./configureオプションはネット上で検証されてないように思う
homebrewがするopensslインストールにおいて、./configureオプションはネット上で検証されてないように思う全てソースビルドされた場合。
openssl作者の意図(./configureオプション)
curl作者の意図
ruby作者の意図
(rbenv、ruby-buildなし)
最も問題が少なそう?だけならともかく、加えてhomebrewの理解と意図がある場合。
homebrew作者が上記の意図を理解した(かもしれないので間違いがあるかも?)上での
opensslの./configureオプション
curlの./configureオプション
rubyの./configureオプション
(rbenv、ruby-buildなし)さらに加えて、rbenv(ruby-build)ビルドされた場合。
rbenv(ruby-build)作者が意図する
opensslの./configureオプション理解(インスト済みの環境を把握する)
curlの./configureオプション(インスト済みの環境を把握する)
rubyの./configureオプションさらに場合分けで、全てhomebrewビルドされた場合。
rbenv(ruby-build)の意図する
opensslの./configureオプション理解(インスト済みの環境を把握する)
curlの./configureオプション(インスト済みの環境を把握する)
rubyの./configureオプション
この場合だけは二番目に問題が少なそうではあるが、疑問が残った結果だ。ツールが多ければ問題の切り分けが難しいのは分かってもらえると思う。
一番下の全てhomebrewに任せる場合も不具合がある。
組み合わせはともかく、kindai.rb動作に至るまでにSSL関連の失敗、不具合(不明瞭?)今までopenssl、curl、ruby、rbenvのインストールを何度やり直したか分からない。インストール(configureオプション)と使い方で
opensslの質問
curlの質問
rubyの質問
等々、それぞれがネットに大量にある状態だ。(ありすぎて問題だ。)数年間、筆者はqitta以外でもインストール記事を読んできたが、今まで上記の点を指摘か注意した記事を一つも見当たらなかった。(linuxでなくMacだからかもしれないが。)
openssl、curl、ruby、rbenvのインストールを何度もやり直し失った時間を考えると
今回で筆者はソースビルドが一番早いと考えを改めるようになった。記憶と推測だけで申し訳ない。
過去のインストールログが全て残っておらず突っ込み所は多数があるが、ご容赦を。以上