- 投稿日:2020-10-15T23:48:58+09:00
rails 新規アプリケーション立ち上げコマンド
Ruby on Railsでの新規アプリケーション立ち上げ方法
自分に向けて記憶の範囲内だけでアウトプットします!
①
ターミナルrails _6.0.0_ new test -d mysql②
ターミナルrails db:create③
ターミナルrails g model test④
db/migrate/2020・・・・・t.string :name, null: false (ここの行の記述は適当)⑤
ターミナルrails db:migrate⑥
config/routes.rbroot to tests#index (ここの行も適当)⑦
ターミナルrails g controller tests⑧
app/controller/tests.controller.rbdef index @tests = Test.all end⑨
database.ymlutf8○○・・・の箇所をutf8のみにする⑩
app/views/index.html.erbここにHTMLを記述する
以上!
ここまで全て記憶内で書いてみました。足りないところや間違っているところもあると思いますが、私自身は間違っているところがあればエラー見ればわかるのでこれを参考にする方は100%信じきらないでください!
現場からは以上です!
- 投稿日:2020-10-15T23:35:01+09:00
PCの開発環境で作ったWEBアプリをスマホでも確認する方法
最近個人開発アプリのレスポンシブ化を行いました。
デベロッパツールでも見れますが、実機でもちゃんと表示されるか確認したいですよね。そんな時に手軽にスマホアプリでも確認する方法を共有させて頂きます。【環境】
- windows10 Pro
- Rails: 6.0.3.2
- ruby: 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
- Docker for windows
- MySQL 5.7
- nginx:1.15.8
手順
まず、PCとスマホを同じWiFiに繋ぎます。
その後、Windowsキー+Rを押し、cmdと入力します。
コマンドプロンプトを開くので、ipconfigと入力しエンターを押します。イーサネット アダプター VirtualBox Host-Only Network: (省略) イーサネット アダプター VirtualBox Host-Only Network #2: (省略) イーサネット アダプター vEthernet (Extarnal Virtual Switch): 接続固有の DNS サフィックス . . . . .: flets-west.jp IPv6 アドレス . . . . . . . . . . . .: 240xxxxxxxxxx 一時 IPv6 アドレス. . . . . . . . . .: 240xxxxxxxxxxxxxxxx リンクローカル IPv6 アドレス. . . . .: xxxxxxxxxxxxxxxx IPv4 アドレス . . . . . . . . . . . .: 192.168.1.193//この部分を覚えておく サブネット マスク . . . . . . . . . .: xxxxxxxxxxxxxxx デフォルト ゲートウェイ . . . . . . .: xxxxxxxxxxxxxxxxxxx入力すると↑のように色々でてきますので、おそらくですが、仮想環境にDockerを使っている場合、イーサネット アダプター vEthernet (Extarnal Virtual Switch)と書いてある欄のIPv4のIPアドレスをスマホのブラウザから入力するとアクセスできると思います。
(例:3000番ポートを開放している場合、http://192.168.1.193:3000/ とすると、PCの開発環境にアクセスできます。)開発環境が違う場合、他のIPアドレスを入力する必要があると思いますので、適時つながるアドレスを見つけてください!
最後まで読んでいただきありがとうございます!
このように日々学んだことをアウトプットしてます!少しでも皆様のお役に立てれば幸いです!ご指摘などあればコメントいただけますと嬉しいです!
- 投稿日:2020-10-15T23:30:29+09:00
if文で論理演算子をたくさん使いたいの巻
はじめに
本日学んだ、if文で条件を重ねたいときに、論理演算子をどう使うかについてまとめる。
論理演算子
&&→かつ
例if a && b #処理 endaとbの両方がtrueのとき、処理が実行される。
||→または
例if a || b #処理 endaかbのどちらかがtrueであれば処理が実行される。
!a
trueとfalseが反対になる。
例if !a #処理 endaが本当はfalseだと、処理が実行される。(falseがtrueに変わるため)
複数の論理演算子をif文で使う
簡単に言ってしまえば、( )を使って、まとまりを括る。
例
if ( a && b ) || ( !a && !b ) #処理 end||があるため、左辺か右辺がtrueであれば、処理が実行される。
左辺は「aかつbがtrue」であれば、左辺全体としてtrueになる。
右辺は「aかつbが本当はfalse」であれば、右辺全体としてtrueになる。
要は、aとbがtrueかfalseで一致してれば、処理が実行されるというコード。さいごに
高校の数Aでやったような内容だなぁ…
- 投稿日:2020-10-15T23:16:54+09:00
rails db:migrateでエラー(StandardError: An error has occurred, this and all later migrations canceled:が出た時の対処
はじめに
これは学習用のメモになります。
今回は$rails db:migrate、または、$rails db:migrateを行った後のエラーが出た時の対処をしていきます。
== 20200107095832 CreateMicroposts: migrating ================================= -- create_table(:microposts) rails aborted! StandardError: An error has occurred, this and all later migrations canceled: SQLite3::SQLException: table "microposts" already exists: CREATE TABLE "microposts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" text, "user_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) 以下つづく原因
この前に行ったコマンドのmigrationで何らかの手違いがあると思います。おそらく、migration処理の途中からエラーが起きていて、テーブルは生成されているが、テーブルを生成したmigrationは未実行のまま。といった状態なのかな?と思います
解決策
①
$ rails db:migrate:resetデータベースのリセットを行った後
$ rails db:migrateもう一度マイグレーション
データベースを削除し、新しくmigrationファイルを修正して、もう一度migrationを行いたい場合に使うコマンドです。
②
$ rails db:migrate:resetデータベースのリセットを行った後エラーが発生!
ActiveRecord::NoEnvironmentInSchemaError: Environment data not found in the schema. To resolve this issue, run: bin/rails db:environment:set RAILS_ENV=development Tasks: TOP => db:migrate:reset => db:drop => db:check_protected_environments (See full trace by running task with --trace)対処
rake db:migrate:status上記のコマンドでdbのステータスを確認します。
⬇︎実行内容up 20201013130002 Devise create users down 20201015132219 Add devise to usersどうやら、一番下のマイグレーションファイルが怪しい。。。
エディタを確認したところ
同じマイグレーションファイルを二回作成していました。。
なので、一番下のマイグレーションファイルを削除してみます。
※downの状態だったら、手動でファイルを削除しても問題ない$ rm -rf db/migrate/20201015132219_add_devise_to_users.rbこれでもう一度マイグレーションを行う。
⬇︎実行結果== 20201013130002 DeviseCreateUsers: migrating ================================ -- create_table(:users) -> 0.0061s -- add_index(:users, :email, {:unique=>true}) -> 0.0014s -- add_index(:users, :reset_password_token, {:unique=>true}) -> 0.0011s == 20201013130002 DeviseCreateUsers: migrated (0.0087s) =======================問題なくできました!
最後に
今回はマイグレーションした際のエラーについて学習しました。
DBリセットしても解決しませんでした。
原因はマイグレーションファイルが重複していたためでした。間違っているところがあればご指摘いただけると幸いです。
- 投稿日:2020-10-15T22:55:33+09:00
Railsチュートリアル備忘録2
環境
macOS Catalina 10.15.5
Rails 6.0.3Railsチュートリアルとそれに付随するいろいろを書いていきます。
Githubに慣れたいので、チュートリアルは第6版に準拠しています。1.5.1 Herokuのセットアップとデプロイ
リスト 1.21
$ heroku create
› Warning: heroku update available from 7.42.13 to 7.43.0. Creating app... done, ⬢ ***** https://*****.herokuapp.com/ | https://git.heroku.com/*****.git
$ git push heroku master
remote: LoadError: cannot load such file -- uglifiererror: failed to push some refs to 'https://git.heroku.com/*****.git'下記を参考に、
https://algorithm.joho.info/heroku/error-failed-to-push-some-refs-to/
$ git fetch
$ git rebase heroku/master
を実行したが、下記のようになり解決せず。fatal: invalid upstream 'heroku/master'また、下記を参考に、
https://ja.stackoverflow.com/questions/67934/git-push-heroku-master%E3%81%A7%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B%E3%82%A8%E3%83%A9%E3%83%BC-precompiling-assets-failed-error-failed-to-pu
Gemfile にuglifier
のgem追加をしてみる。Gemfilegem 'bootsnap', '1.4.5', require: false gem 'uglifier'再度、下記実行
$ git commit -a -m "Update Gemfile for Heroku"
$ git push heroku master
remote: LoadError: cannot load such file -- uglifier
は消えたが
error: failed to push some refs to~
は変わらず。
$ git push heroku master
実行時のエラーに下記があった。remote: ###### WARNING: remote: remote: This buildpack was created as a stop-gap measure to allow running applications with Bundler 2 on Heroku. remote: Heroku now supports Bundler 2 directly: https://devcenter.heroku.com/changelog-items/1563 remote: remote: Please discontinue use of this buildpack and instead directly use the `heroku/ruby` buildpack. remote: remote: To remove this buildpack use the `heroku buildpacks` command to list your existing buildpacks. remote: remote: If you only have one buildpack listed you can run: remote: remote: ``` remote: heroku buildpacks:set heroku/ruby remote: ``` remote: remote: If you have multiple buildpacks, you'll need to add the buildpack to the correct location using remote: `heroku buildpacks:add heroku/ruby -i <correct index>` and then remove this buildpack via: remote: remote: ``` remote: heroku buildpacks:remove https://github.com/bundler/heroku-buildpack-bundler2 remote: ```
$ heroku buildpacks
では下記のBuildpackのみ。https://github.com/bundler/heroku-buildpack-bundler2そのため
$ heroku buildpacks:set heroku/ruby
を実行。Buildpack set. Next release on pacific-atoll-18588 will use heroku/ruby. Run git push heroku main to create a new release using this buildpack.再度
$ git push heroku master
すると今度は下記の警告。remote: webpack binstubs not found. remote: Have you run rails webpacker:install ? remote: Make sure the bin directory or binstubs are not included in .gitignore remote: Exiting!https://archive.blog.inomar.me/2018/08/19/rails5-1%E3%81%A7webpack%E3%81%8C%E4%BD%BF%E7%94%A8%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%AE%E3%81%A7vuejs%E3%81%A7%E9%81%8A%E3%82%93%E3%81%A7%E3%81%BF%E3%81%9F/
上記を参考にして$ bundle exec rails webpacker:install
を実行。
再度$ git push heroku master
しても上記の警告が消えず。remote: webpack binstubs not found. remote: Have you run rails webpacker:install ? remote: Make sure the bin directory or binstubs are not included in .gitignore remote: Exiting!
$ git push heroku main
を実行。error: src refspec main does not match any error: failed to push some refs to 'https://git.heroku.com/*****.git'
$ git push heroku main -f
で強制プッシュしようとしても同じ結果だったので
gitのリポジトリを削除・再作成し、herokuのアプリも再作成してadd、commit、pushを行ったが、
以下のエラーは消えず…! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to 'https://git.heroku.com/*****.git'ダメ元で再度
$ git push heroku main -f
を実行したところ、ようやく完了。
無意味なダウンロード等を結構してしまったと思うのでこの後無事に動作するのかが不安…
- 投稿日:2020-10-15T21:54:55+09:00
トランザクションシミュレータ
トランザクションの検証が面倒すぎる。モデルとしては単純そうだから、作ってしまおう、と思った。
Ruby
ruby.trans.rbclass Command end class Begin < Command end class Rollback < Command end class Commit < Command end class Read < Command attr_reader :var def initialize(var) @var = var end end class Write < Command attr_reader :var,:val def initialize(var,val) @var = var @val = val end end class Lock attr_reader :tr,:var,:type def initialize(tr,var,type) @tr=tr @var=var @type=type end end class Unlock attr_reader :tr,:var def initialize(tr,var) @tr= tr @var=var end end class Insert attr_reader :var,:val def initialize(var,val) @var=var @val=val end end class Delete attr_reader :var def initialize(var) @var=var end end class Event attr_reader :tr,:cmd # tr :String # cmd : Command def initialize(tr, cmd) @tr = tr @cmd = cmd end end class Database attr_reader :vars # vars : Map<var_name,value> def initialize(vars) @vars = vars end end class Transaction attr_accessor :name,:vars def initialize(name) @name=name @vars= {} end end class State attr_reader :db,:events,:pointer,:trs def initialize(db,events,trs) @db = db @locks = [] @events = events @pointer = 0 @trs = trs end def next() e = @events[@pointer] if e then if e.cmd.is_a?(Begin) then puts "Begin #{e.tr}" elsif e.cmd.is_a?(Rollback) then puts "Rollback #{e.tr}" elsif e.cmd.is_a?(Commit) then puts "Commit #{e.tr}" elsif e.cmd.is_a?(Read) then if @locks.filter {|l| l.tr != e.tr && l.var == e.cmd.var && l.type == :Exclusive}.empty? then puts "Read #{e.tr} var=#{e.cmd.var} => val=#{@db.vars[e.cmd.var]}" else puts "Read #{e.tr} var=#{e.cmd.var} => Read failed. This variable is locked by another transaction." raise("Reading failure") end elsif e.cmd.is_a?(Write) then if @locks.filter {|l| l.tr != e.tr && l.var == e.cmd.var}.empty? then pre = @db.vars[e.cmd.var] @db.vars[e.cmd.var]=e.cmd.val puts "Write #{e.tr} var=#{e.cmd.var} val=#{e.cmd.val} => db[#{e.cmd.var}]: #{pre} => #{@db.vars[e.cmd.var]}" else puts "Write #{e.tr} var=#{e.cmd.var} val=#{e.cmd.val} => This variable is locked by another transaction." raise("Writing failure") end elsif e.cmd.is_a?(Lock) then if @locks.filter {|l| l.tr != e.cmd.tr && l.var == e.cmd.var && l.type == :Exclusive}.empty? then @locks << e.cmd puts "Lock #{e.tr} var=#{e.cmd.var} type=#{e.cmd.type} => Success." else puts "Lock #{e.tr} var=#{e.cmd.var} type=#{e.cmd.type} => This variable is locked by another transaction. Getting lock was failed." raise("Locking failure") end elsif e.cmd.is_a?(Unlock) then @locks.filter!{|l| !(l.tr == e.tr && l.var == e.cmd.var)} puts "Unlock #{e.tr}" elsif e.cmd.is_a?(Insert) then if @db.vars[e.cmd.var].nil? then @db.vars[e.cmd.var] = e.cmd.val puts "Insert #{e.tr} var=#{e.cmd.var} val=#{e.cmd.val} => Success." else puts "Insert #{e.tr} var=#{e.cmd.var} val=#{e.cmd.val} => This variable is already exists. Insertion was failed." raise("Insertion failure") end elsif e.cmd.is_a?(Delete) then if !@locks.filter{|l| l.tr != e.tr && l.var == e.cmd.var}.empty? then puts "Delete #{e.tr} var=#{e.cmd.var} => This variable is locked by another transaction. Deletion was failed." raise("Deletion failure") end if @db.vars[e.cmd.var].nil? then puts "Delete #{e.tr} var=#{e.cmd.var} => No such variable. Deletion was failed." raise("Deletion failure") end @db.vars.delete(e.cmd.var) @locks.filter! {|l| !(l.tr == e.tr && l.var == e.cmd.var)} puts "Delete #{e.tr} var=#{e.cmd.var} => Success" else puts "Other" end else # the last of events end @pointer += 1 end end @events = [ Event.new("tr_a",Begin.new()), Event.new("tr_b",Begin.new()), Event.new("tr_a",Lock.new("tr_a","X",:Shared)), Event.new("tr_a",Read.new("X")), Event.new("tr_b",Read.new("X")), Event.new("tr_a",Lock.new("tr_a","X",:Exclusive)), Event.new("tr_a",Write.new("X",20)), Event.new("tr_a",Unlock.new("tr_a","X")), Event.new("tr_b",Read.new("X")), Event.new("tr_b",Insert.new("Y",12)), Event.new("tr_b",Delete.new("Y")), Event.new("tr_a",Commit.new()), Event.new("tr_b",Commit.new()) ] @vars = {"X" => 10} @db = Database.new(@vars) @trs = { "tr_a" => Transaction.new("tr_a"), "tr_b" => Transaction.new("tr_b"), } @state = State.new(@db,@events,@trs) @events.each_index {|i| printf("%3d ",i) @state.next() }実行結果
0 Begin tr_a 1 Begin tr_b 2 Lock tr_a var=X type=Shared => Success. 3 Read tr_a var=X => val=10 4 Read tr_b var=X => val=10 5 Lock tr_a var=X type=Exclusive => Success. 6 Write tr_a var=X val=20 => db[X]: 10 => 20 7 Unlock tr_a 8 Read tr_b var=X => val=20 9 Insert tr_b var=Y val=12 => Success. 10 Delete tr_b var=Y => Success 11 Commit tr_a 12 Commit tr_bこんな感じ。
別のトランザクションイベント。Xの排他ロックがかかっていた場合。
Event.new("tr_a",Begin.new()), Event.new("tr_b",Begin.new()), Event.new("tr_a",Lock.new("tr_a","X",:Exclusive)), Event.new("tr_a",Read.new("X")), Event.new("tr_b",Read.new("X")),0 Begin tr_a 1 Begin tr_b 2 Lock tr_a var=X type=Exclusive => Success. 3 Read tr_a var=X => val=10 4 Read tr_b var=X => Read failed. This variable is locked by another transaction. Traceback (most recent call last): 3: from tran.rb:182:in `<main>' 2: from tran.rb:182:in `each_index' 1: from tran.rb:184:in `block in <main>' tran.rb:103:in `next': Reading failure (RuntimeError)tr_bの読み込みがロックされて、このイベント列は失敗する。
振り返り
次はロック待ちの状況をモデリングしていこう。片方のトランザクションが終われば、もう片方のロック待ちも解消される、というパターン。
まともにテスト書いて、モデルを検証する必要がある。
MVCCではなくて、単純なロック機構でのシミュレーションなので、MVCCのつもりでイベント列を見ていると混乱する。
- 投稿日:2020-10-15T20:26:55+09:00
画像を複数件保存・表示する
実装したい事
画像実装機能は実装済みで、複数件の写真を保存・表示させる。
1.モデルのアソシエーション変更
変更前
class Scene < ApplicationRecord belongs_to :user has_one_attached :image 省略 end変更後
class Scene < ApplicationRecord belongs_to :user has_many_attached :images 省略 end2.コントローラーの変更
変更前
class ScenesController < ApplicationController def new @scene = Scene.new end def create @scene = Scene.new(scene_params) if @scene.save redirect_to root_path else render :new end end def show @scene = Scene.find(params[:id]) end private def scene_params params.require(:scene).permit(:name, :user_name, :comment, :image).merge(user_id: current_user.id) end end変更後
class ScenesController < ApplicationController def new @scene = Scene.new end def create @scene = Scene.new(scene_params) if @scene.save redirect_to root_path else render :new end end def show @scene = Scene.find(params[:id]) end private def scene_params params.require(:scene).permit(:name, :user_name, :comment, image: []).merge(user_id: current_user.id) end end3.ビューの変更
投稿ページ
変更前
<%= form_with model: @scene, local: true do |f| %> <div class="img-upload"> <div class="weight-bold-text"> 現場画像 <span class="indispensable">必須</span> </div> <div class="click-upload"> <p> クリックしてファイルをアップロード </p> <%= f.file_field :image, id:"item-image"%> </div> </div> 省略 <% end %>変更後
<%= form_with model: @scene, local: true do |f| %> <div class="img-upload"> <div class="weight-bold-text"> 現場画像 <span class="indispensable">必須</span> </div> <div class="click-upload"> <p> クリックしてファイルをアップロード </p> <%= f.file_field :image, multiple: true , id:"item-image"%> </div> </div> 省略 <% end %>閲覧ページ
変更前
省略 <%= image_tag image %> 省略変更後
<% @scene.image.each do |image| %> <%= image_tag image %> <% end %>上記の変更点で、複数件の写真の投稿・表示が可能となりました。
今後について
写真の表示方法が横並びにしているだけなので、間隔を空けながらビューファイルを整理する。
- 投稿日:2020-10-15T19:16:05+09:00
プログラミングコードを販売できるサービス「Code-sell」をリリースした!
初めに
今回、約2か月ぶりにwebアプリを公開しました。
プログラミングコードを販売できるサービス Code-sellです。なるべく気軽に販売・購入できるように工夫しました。
100円から価格設定できます。
ちなみに僕が今まで作ってきた4つのwebアプリのコードをすべて無料で公開しています!
ほしい人いるかわからないけど何かの参考にでも...。↑topページ
なぜ作ったか
今まで作ったwebアプリを販売(譲渡)しようと思ったのですが権利の問題や面会などめんどくさそうなものがたくさん出てきました。そんな時に思いつきました。Code-sellは譲渡はせずコードをダウンロードするだけなので権利の問題も考えなくていいですし、面会ももちろんありません。
できること
google認証
stripeを使った、購入、送金
いいね
通知
言語タグ・説明タグとかです。基本的な機能しかいまはありません...。
使った技術
rails6
ruby2.7
stripe
postgresql
slim
ridgepoleくらいですかね。
このなかでもstripeには本当に苦労しました。
情報はあるんですがどれもこれもコードの説明?で実践的な情報が本当に少ないです。
なので組み立てるのにかなり時間をかけました。
絶対にstripeに関する記事を出すと約束します。終わりに
読んでくれてありがとうございました。code-sell使ってみてください!
https://www.code-sell.net/
- 投稿日:2020-10-15T19:16:05+09:00
プログラミングコードを販売できるサービス「Code-sell」をリリースした(個人開発)
初めに
今回、約2か月ぶりにwebアプリを公開しました。
プログラミングコードを販売できるサービス Code-sellです。なるべく気軽に販売・購入できるように工夫しました。
100円から価格設定できます。
ちなみに僕が今まで作ってきた4つのwebアプリのコードをすべて無料で公開しています!
ほしい人いるかわからないけど何かの参考にでも...。↑topページ
なぜ作ったか
今まで作ったwebアプリを販売(譲渡)しようと思ったのですが権利の問題や面会などめんどくさそうなものがたくさん出てきました。そんな時に思いつきました。Code-sellは譲渡はせずコードをダウンロードするだけなので権利の問題も考えなくていいですし、面会ももちろんありません。
できること
google認証
stripeを使った、購入、送金
いいね
通知
言語タグ・説明タグとかです。基本的な機能しかいまはありません...。
使った技術
rails6
ruby2.7
stripe
postgresql
slim
ridgepole
JavaScriptくらいですかね。
このなかでもstripeには本当に苦労しました。
情報はあるんですがどれもこれもコードの説明?で実践的な情報が本当に少ないです。
なので組み立てるのにかなり時間をかけました。
絶対にstripeに関する記事を出すと約束します。終わりに
読んでくれてありがとうございました。ぜひcode-sell使ってみてください!
https://www.code-sell.net/※まだ公開したばかりなので不具合を見つけたらお問い合わせフォームやらQiitaのコメントなどで教えてください。お願いします。
- 投稿日:2020-10-15T19:16:05+09:00
コードを販売できるサービス「Code-sell」をリリースした(個人開発)
初めに
今回、約2か月ぶりにwebアプリを公開しました。
プログラミングコードを販売できるサービス Code-sellです。なるべく気軽に販売・購入できるように工夫しました。
100円から価格設定できます。
ちなみに僕が今まで作ってきた4つのwebアプリのコードをすべて無料で公開しています!
ほしい人いるかわからないけど何かの参考にでも...。↑topページ
なぜ作ったか
今まで作ったwebアプリを販売(譲渡)しようと思ったのですが権利の問題や面会などめんどくさそうなものがたくさん出てきました。そんな時に思いつきました。Code-sellは譲渡はせずコードをダウンロードするだけなので権利の問題も考えなくていいですし、面会ももちろんありません。
できること
google認証
stripeを使った、購入、送金
いいね
通知
言語タグ・説明タグとかです。基本的な機能しかいまはありません...。
使った技術
rails6
ruby2.7
stripe
postgresql
slim
ridgepole
JavaScriptくらいですかね。
このなかでもstripeには本当に苦労しました。
情報はあるんですがどれもこれもコードの説明?で実践的な情報が本当に少ないです。
なので組み立てるのにかなり時間をかけました。
絶対にstripeに関する記事を出すと約束します。終わりに
読んでくれてありがとうございました。ぜひcode-sell使ってみてください!
https://www.code-sell.net/※まだ公開したばかりなので不具合を見つけたらお問い合わせフォームやらQiitaのコメントなどで教えてください。お願いします。
- 投稿日:2020-10-15T19:16:05+09:00
コードを販売できるサービス「Code-sell」をリリースした!(個人開発)
追記
メール認証のエラーを修正しました。
いままで気づけなくてすみませんでした。初めに
今回、約2か月ぶりにwebアプリを公開しました。
プログラミングコードを販売できるサービス Code-sellです。なるべく気軽に販売・購入できるように工夫しました。
100円から価格設定できます。
ちなみに僕が今まで作ってきた4つのwebアプリのコードをすべて無料で公開しています!
(今非公開にしています。すみません。)
ほしい人いるかわからないけど何かの参考にでも...。↑topページ
なぜ作ったか
今まで作ったwebアプリを販売(譲渡)しようと思ったのですが権利の問題や面会などめんどくさそうなものがたくさん出てきました。そんな時に思いつきました。Code-sellは譲渡はせずコードをダウンロードするだけなので権利の問題も考えなくていいですし、面会ももちろんありません。
できること
google認証
stripeを使った、購入、送金
いいね
通知
言語タグ・説明タグとかです。基本的な機能しかいまはありません...。
使った技術
rails6
ruby2.7
stripe
postgresql
slim
ridgepole
JavaScriptくらいですかね。
このなかでもstripeには本当に苦労しました。
情報はあるんですがどれもこれもコードの説明?で実践的な情報が本当に少ないです。
なので組み立てるのにかなり時間をかけました。
絶対にstripeに関する記事を出すと約束します。終わりに
読んでくれてありがとうございました。ぜひcode-sell使ってみてください!
https://www.code-sell.net/※まだ公開したばかりなので不具合を見つけたらお問い合わせフォームやらQiitaのコメントなどで教えてください。お願いします。
- 投稿日:2020-10-15T18:49:39+09:00
SSHでポートフォワード接続して、ファイルの送受信をする
環境
Ubuntu 16.04.7 LTS (Xenial Xerus)
ruby 2.5.0p0やりたい事
Rubyプログラムをポートフォワードで指定したサーバーに転送した後、転送先のサーバーでRubyプログラムを実行させて、csvファイルを標準出力させます。そして、標準出力したcsvファイルを、自分のローカル環境に持ってくるという事をやります。
コード
def ssh_connect begin # ファイルを転送 _cmd = system('scp -P 54322 -i /home/.ssh/id_rsa /home/syori.rb server@153.153.xx.xx:/home') # ポートフォワードの設定 Net::SSH.start( '153.153.xx.xx', 'username', :keys => '/home/.ssh/id_rsa', :port => 54322 ) do |_a| _a.forward.local(2222,'192.168.xx.xx', 54323) _a.exec!('ruby syori.rb') end # ファイルを取得する _cmd = system('scp -P 54322 -i /home/.ssh/id_rsa server@153.153.xx.xx:/home/users.csv /home') rescue => ex print "***** " + self.class.name.to_s + "." + __method__.to_s + " *****\n" print(ex.class," -> ",ex.message) end end解説
system
RubyでLinuxコマンドを発行するメソッドです。戻り値は、ture/falseが返ってきます。
scp
ファイル転送するコマンド(プロトコル)です。ファイル転送というと、ひと昔はftpがよく使われていたと思いますが、ftpはログインする時のアカウント情報を暗号化できないため、セキュリティを高めるために、SSH機能が標準装備されているscpを使う事が基本になります。
scpのオプション
-P
ポート番号を指定します。SSHのポート番号は22が、ウェルノウンポート番号として指定されていますが、外向けに公開しているサーバーであれば、変な攻撃を受けないために、カスタマイズしている場合があると思います。接続するサーバーのSSHのポート番号を指定します。
-i
SSH通信で利用する公開鍵を保存しているパスを絶対パスで設定します。大抵、ホームの.sshに置かれます。
転送するファイル名を絶対パスで設定します。転送先の指定は、転送先のサーバー名:転送先のディレクトリを絶対パスで指定します。
ポートフォワードの解説
Net::SSH.start( フォワード元IPアドレス, フォワード元のユーザー名, :keys => 接続元の秘密鍵の絶対パス, :port => 接続元のポート番号 ) do |_a| _a.forward.local(フォワード元のポート番号(何でもいい), 'ポートフォワード先のIPアドレス', フォワード先のポート番号) _a.exec!('接続先で実行したいコマンド') end
- 投稿日:2020-10-15T18:43:52+09:00
[Rails]Active Hashの導入
はじめに
Active_Hashとは、都道府県名やカテゴリー選択などの変更されないデータをモデルファイル内に直接記述することで、データベースへ保存せずにデータを取り扱うことができるgemです。
Active_Hashを用いることで、モデルファイルに直接記述した変更されないデータに対して、ActiveRecordのメソッドを用いることができます。目次
1.Active Hashのインストール
2.モデルの作成
3.マイグレーションファイルの編集
4.アソシエーションの設定
5.ビューファイルの編集1. Active Hashのインストール
gemfileに以下を記述します。
その後、コマンドでbundle installを実行します。gemfilegem 'active_hash'2. モデルの作成
今回はPostモデルとCategoryモデルを作成します。
Postモデルはいつも通りに作成します。ターミナル
rails g model postCategoryモデルを作成する際は、「--skip-migration」オプションを使用します。
「--skip-migration」を使用することで、マイグレーションファイルの生成を行わないようにします。
今回、カテゴリーを情報をデータベースには保存をしないのでマイグレーションファイルを作成しません。ターミナル
rails g model category --skip-migrationcategory.rbでCategoryクラスを定義し、ActiveHash::Baseクラスを継承します。
ActiveHash::Baseを継承することで、Categoryモデルに定義したオブジェクトに対してActiveRecordのメソッドが使用できるようになります。app/models/genre.rbclass Category < ActiveHash::Base self.data = [ { id: 1, name: '---' }, { id: 2, name: '化粧水' }, { id: 3, name: '乳液' }, { id: 4, name: 'オールインワン' }, { id: 5, name: 'クレンジング' }, { id: 6, name: '洗顔料' }, { id: 7, name: '日焼け止め' }, { id: 8, name: 'リップ' }, { id: 9, name: '香水' }, { id: 10, name: 'ヘアカラー' }, { id: 11, name: 'ヘアスタイリング' }, { id: 12, name: 'シャンプー・コンディショナー' }, { id: 13, name: 'コンタクトレンズ' } ] endデータは配列にハッシュの形で格納しています。
3. マイグレーションファイルの編集
postsテーブルにはcategory_idカラムを作成します。
_idになっているのはidに紐づいているカテゴリーを取得し、カテゴリーのidをpostsテーブルに保存するからです。
カラム型はinteger型にします。db/migrate/20XXXXXXXXXXXX_create_articles.rb~略~ t.integer :category_id, null: false ~略~4. アソシエーションの設定
ActiveHashにはbelongs_to_active_hashメソッドが用意されています。
ActiveHashを使って作成したモデルに対してアソシエーションを設定する場合は、belongs_to_active_hashメソッドを使います。
ActiveHash::Associations::ActiveRecordExtensionsを記述することで、belongs_to_active_hashメソッドを使用できます。app/models/post.rbclass Post < ApplicationRecord extend ActiveHash::Associations::ActiveRecordExtensions belongs_to_active_hash :category end5. ビューファイルの編集
今回はデータをプルダウン形式で表示しました。
ですので、collection_selectメソッド使って表示します。<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目(表示する際に参照するDBのカラム名), 選択肢に表示されるカラム名, オプション, htmlオプション(classなど)) %>例
app/views/posts/new.html.erb<%= f.collection_select(:category_id, Category.all, :id, :name, {}, {class:”category-select"}) %>参考リンク
- 投稿日:2020-10-15T17:55:12+09:00
Herokuへのデプロイ【Ruby on Rails】初心者
開発環境:macOS Catalina/GitHub/MySQL
※Herokuへのユーザー登録完了後の手順です。
備忘録として残したいと思い、記事にしました。
初心者なので、至らない点があるかと思いますがその際はコメントいただけたらと思います。1. Heroku CLIをインストールする
コマンド
% brew tap heroku/brew && brew install herokuバージョンの確認
% heroku --versionバージョンが出力されたらインストール完了
公式サイト:https://devcenter.heroku.com/articles/heroku-cli
2. ログインする
% heroku login --interactive Email: それぞれ入力 password: それぞれ入力登録したメールアドレスがLogged in asの後に表示されていればログイン成功
3. Gemの導入
Gemfile ※一番下に入力
Gemfilegroup :production do gem 'rails_12factor' endbundle installと再起動をお忘れなく
Gitで管理している場合はコミットしておきます
4. Heroku上にアプリケーションを作成する
% heroku create [アプリケーション名] % git config --list | grep herokuこの時、"fatal: not in a git directory"以外が出力されていれば作成完了です!
5. MySQLを使えるようにするコマンド
% heroku addons:add cleardb % heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL` % heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}URLの"mysql2"はGemの使用状況によって変更する
以降は非公開の値を管理する為の環境変数の設定などを行います。6. 公開を確認するコマンド
% heroku apps:info参考:https://devcenter.heroku.com/articles/getting-started-with-rails6
- 投稿日:2020-10-15T17:47:08+09:00
Railsで生SQLをリードレプリカに投げる
switch_pointというgemを使用するのだが、
readmeにちらっとだけ書いてあって、例が示されてないのでわかりにくいがswitch_point_proxy.model_for_connectionってのを使えばいいみたいhttps://github.com/eagletmt/switch_point
例えばUserモデルだったら、
use_switch_point :slaveみたいに追加して、
rows = [] User.with_readonly do con = User.switch_point_proxy.model_for_connection.connection sql = "select * from users limit 1" rows = con.select_all(sql) endみたいな感じで行けるみたい
- 投稿日:2020-10-15T15:38:02+09:00
Rails Active_storage -画像の保存を簡易化する-
Active storageとは
Active Storageは、ファイルアップロードを行うための機能です。これを使えば、フォームで画像の投稿機能などが簡単に作れます。クラウドストレージサービス(Amazon S3, Google Cloud Storage, Microsoft Azure Storageなど)に対するファイルのアップロードを簡単に行うことができます。
導入方法
- Active_storageに沿ったテーブルを作る
% rails active_storage:installActive_storageをインストールし、関連ファイル(マイグレーションなど)を生成
%rails db:migrateSeaquel Proを確認すると以下のようなテーブルが生成されていたらここまでは成功です。
これで画像を保存するための「入れ物」は完成しました。モデルの記述: 画像1枚を添付する
「メッセージに画像を添付する」、「商品情報に画像を添付する」など画像情報は他モデルと関わることが多くあります。ここでよくあるのが、「imagesテーブルがあるからimageモデルを作ってアソシエーションを組む」という考え方です。実はactive_storageで作成したテーブルに関しては別途モデルを作る必要はなありません。関わらせたいモデルに「has_one_attached :ファイル名」を追記すればアソシエーションは完成します。
今回はメッセージとアソシエーションを組むことを想定していきます。
models/message.rbclass Message < ApplicationRecord ~他 associationなどの記述は省略~ has_one_attached :image endアソシエーションというよりも、「擬似的な画像カラムを作った」と言った方がイメージしやすいかもしれません。
コントローラの記述: ストロングパラメータ
seaquel_proのmessageテーブルを見てみると、imageカラムは存在していません
しかしながらモデルで記述したhas_one_attachedによって、messagesテーブルには「擬似的なimageカラム」が存在していることになっています。
※画像情報はrails active_storage:installで生成したテーブル内に保存されます。このことからmessages_controller.rb内のparamsで画像の情報が飛ばせるようになりました。
controllers/messages_controller.rb
class MessagesController < ApplicationController def new @message = Message.new end def create @mesage = Message.create(message_params) end private def message_params params.require(:message).permit(:content, :image).merge(user_id: current_user.id) end endビューの記述: 画像の送信
ここに関してはいつも通りform要素のfile_fieldを使います。
<%= form_with model: @message, local: true do |form| %> <%= form.text_area :content %><br> <%= form.file_field :image %><br> <%= form.submit %> <% end %>ビューの記述: 画像の表示
imgタグでも可能ですが、railsのヘルパーメソッドであるimage_tagを使って記述を簡略化します。
<% if @message.image.attached? %> <%= image_tag @message.image %> <% end %>以上です!!
- 投稿日:2020-10-15T14:14:51+09:00
【Rails】deviseで現在ログインしているユーザー情報の取得方法
はじめに
deviseでは「現在ログインしているユーザーの情報を取得」する事ができます。
例えば、「名前」「生年月日」「住所」「電話番号」など、対象のユーザーが既に登録した情報を表示する方法を紹介します。目次
1.current_userメソッド
2.遷移先のview開発環境
ruby 2.6.5
rails 6.0.0
devise 4.7.3前提
devise導入済み
model生成済み
ユーザー登録済みでデータを既に持ってる
view作成済み実装
それでは実装して行きます。
1.current_userメソッド
deviseを導入しているため使用できるメソッドで、current_user(現在ログインしているユーザー)の情報が取得できます。
index.html.erb<%= link_to current_user.nickname, edit_user_registration_path(current_user), class: "user-name" %> #↑ここ# #↑ここ#例えば、マイページでユーザー情報を編集したい時を想定します。link_toメソッドでcurrent_user.nameと記述すると、今ログインしてるユーザーのnameカラムに保存されてる名前が表示れます。
また、url指定したpathの後ろにcurrent_userをつける事で、遷移先にもそのユーザー情報を表示させる事ができます。※注意:urlはreils routesでコントローラー#アクションを探しください。
2.遷移先のview
遷移先のviewページでは、既に登録されてるユーザーの情報を表示させます。
edit.html.erb<%= form_with model: @user, url: edit_addresses_path, class: 'registration-main', local: true, method: :get do |f| %> <%= f.text_area :name, class:"input-default", id:"name", placeholder:"例) 太郎", maxlength:"40" %> <% end %>今回ユーザー情報を編集するページを作りたいのでapp> views> devise >registrationsにあるedit.html.erbのファイルを編集します。
form_withメソッドを使います。
devise内部で@userが定義されていて、既にデータが代入されてるので「model: @user」とします。
「do |f|」とする事で「end」までの「f.text_area :カラム名(今回はname)」に現在のユーザー情報が表示されます。※注意:deviseのviewをよび出してる場合は既に生成さてるファイルを使うと便利です。
参考記事
https://qiita.com/AKI3/items/bf0d5b57029abfc8154cまとめ
以上、現在ログインしているユーザー情報の取得方法でした。
current_userメソッドを使う事がポイントです。最後に
私はプログラミング初学者ですが、同じ様に悩んでる方々の助けになればと思い、記事を投稿しております。
それでは、また次回お会いしましょう〜
- 投稿日:2020-10-15T14:00:32+09:00
【Ruby on Rails】Skipprを使用した画像スライドショー
目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina前提
※ ▶◯◯ を選択すると、説明等が出てきますので、
よくわからない場合の参考にしていただければと思います。
- deviseでログイン環境構築
- ログインユーザーのみができる投稿機能
- 投稿の編集機能(更新、削除)
補足
rails g devise:install は deviseの初期設定を行います。流れ
1 gemの導入
2 Skipprサイトからファイルをダウンロード
3 実際のコードgemの導入
Railsでjqueryを使えるようにします。
Gemfilegem 'jquery-rails'ターミナル$ bundle insatllapp/assets/javascripts/application.js//= require jquery ←追加 //= require jquery_ujs ←追加 //= require activestorage //= require turbolinks //= require_tree .Skipprサイトからファイルをダウンロード
公式サイト
http://austenpayan.github.io/skippr/こちらのGithubをクリックし、ZIPファイルをダウンロードしてください。
解凍後、下記の通りに保存してください。
実際のコード
app/assets/imagesにimage1.jpg〜image4.jpgを保存してください。
app/views/application.html.erb<div id="box"> <div id="images"> <div class="image1"></div> <div class="image2"></div> <div class="image3"></div> <div class="image4"></div> </div> </div>app/assets/stylesheets/application.css/* 高さを指定することにより画像が表示される */ #box{ height: 600px; } .image1 { background-image: url(image1.jpg); } .image2 { background-image: url(image2.jpg); } .image3 { background-image: url(image3.jpg); } .image4 { background-image: url(image4.jpg); }app/assets/javascripts/application.js$(document).ready(function () { $("#images").skippr({ // スライドショーの変化 ("fade" or "slide") transition : 'slide', // 変化に係る時間(ミリ秒) speed : 1000, // easingの種類 easing : 'easeOutQuart', // ナビゲーションの形("block" or "bubble") navType : 'block', // 子要素の種類("div" or "img") childrenElementType : 'div', // ナビゲーション矢印の表示(trueで表示) arrows : true, // スライドショーの自動再生(falseで自動再生なし) autoPlay : true, // 自動再生時のスライド切替間隔(ミリ秒) autoPlayDuration : 3000, // キーボードの矢印キーによるスライド送りの設定(trueで有効) keyboardOnAlways : true, // 一枚目のスライド表示時に戻る矢印を表示するかどうか(falseで非表示) hidePrevious : false }); });まとめ
比較的簡単に導入できるものの、
bootstrapと組み合わせるとうまくいかないこともあるので、
その場合はこちらを参考にしてください。
【Ruby on Rails】bootstrap4のcarouselをeachメソッドを使いスライドショーを実装またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork
- 投稿日:2020-10-15T13:56:49+09:00
RubyでのTSVファイルとCSVファイルの取り扱い方
はじめに
この記事では、Rubyにおいて、TSVファイルやCSVファイルを扱う上での基礎知識を、myメモ的な感じでまとめました。TSV,CSV以前に、Fileクラスについても一緒に確認できればと思います。
TSVファイルとは
タブ区切りでデータが格納されたファイル
CSVファイルとは
コンマ( , )区切りでデータが格納されたファイル
本記事では以下のTSVファイルを例にあつかいます
# meibo.txt john m 18 paul m 20 alice f 15 dabid m 17 jasmin f 17Fileクラスについて
ファイルを開く
#書き方1 File.open("meibo.txt") do |file| 処理 end #書き方2 file = File.open("meibo.txt") 処理 file.close書き方1はファイルを開いても勝手に閉じてくれますが、書き方2では
close
メソッドをしないとファイル開きっぱなしです。なので、書き方1の方が個人的には好きです。File.open("meibo.txt") do |file| puts.file end例えば、上記のようにすると、以下のようなFileオブジェクトの標準出力を得ます。
#<File:0x00007fba4497ea68>ファイルを読み込む
開いたファイルは、読み込んだりします。
File.open("meibo.txt") do |file| p file.read endすると、以下のような標準出力になります。
"john\tm\t18\npaul\tm\t20\nalice\tf\t15\ndabid\tm\t17\njasmin\tf\t17\n"いきなり読み込んでも大丈夫です。
file = File.read("meibo.txt") p file #=> "john\tm\t18\npaul\tm\t20\nalice\tf\t15\ndabid\tm\t17\njasmin\tf\t17\n"一行ずつ読みたい場合、以下のように、一度ファイルを開いて、その処理の部分で、一行ずつ読ませて、好きな処理を入れます。
File.open("meibo.txt") do |file| file.each do |line| 処理 end end #例えば File.open("meibo.txt") do |file| file.each do |line| p "#{line.chomp}\tfoo" end end #=> "john\tm\t18\tfoo" "paul\tm\t20\tfoo" "alice\tf\t15\tfoo" "dabid\tm\t17\tfoo" "jasmin\tf\t17\tfoo"以上がFileクラスでの扱い方ですが、出力が数珠つなぎの文字列になっているので、少々扱いづらいかと思います。そこで、CSVクラスを使用することで、データを扱いやすくすることができます。
CSVクラスについて
本来CSVファイルを扱うためのクラスだと思いますが、
col_sep
オプション(指定した文字列で区切ってくれる)を使うとTSVファイルもCVSクラスで扱えます。CSVクラスを使用するときは行頭にrequire "csv"
を付けます。require "csv" #openメソッドを使うなら CSV.open("meibo.txt", col_sep: "\t") do |tsv| p tsv.read end #openメソッドを使わないなら tsv = CSV.read("meibo.txt", col_sep: "\t") p tsv #=> [["john", "m", "18"], ["paul", "m", "20"], ["alice", "f", "15"], ["dabid", "m", "17"], ["jasmin", "f", "17"]]CSVメソッドを用いて読み込むと、出力結果は配列に入れて返されます。
こうすることで、データとして扱いやすくなります。
一行ずつ読ませたいなら以下のforeach
メソッドを使います。require "csv" CSV.foreach("meibo.txt", col_sep: "\t") do |line| 処理 end #例えば CSV.foreach("meibo.txt", col_sep: "\t") do |line| p line end #=> ["john", "m", "18"] ["paul", "m", "20"] ["alice", "f", "15"] ["dabid", "m", "17"] ["jasmin", "f", "17"]こうすることで、各行ごとに配列に対して処理を行うことができます。
ちなみに、もちろんですが、新たにCSVファイルを開いて、そこに書き込むこともできます。
require "csv" CSV.open("meibo.csv","w") do |line| #"w"は書き込みモード line << ["michel","m",16] end # meibo.csv michel,m,16TSVをCSVに変換
最後に、これまでにご紹介した構文を使って、TSVファイルをCSVファイルに変換できます。
いきなり結論ですが、以下です。require "csv" CSV.open('meibo.csv', 'w') do |csv| CSV.foreach("meibo.txt", col_sep: "\t") do |line| csv << line end endまず、書き込みモードでCSVファイルを用意します。そのCSVファイルに、
foreach
でTSVファイルの各行を一行ずつCSVに格納して行くという、流れです。
CSVからTSVについてもこの逆を行えばOKです。さいごに
Fileクラスは最初はちょっとよくわからなかったんですが、この記事書きながら頭の中整理できたので、これからもどんどん使っていこうと思います。
- 投稿日:2020-10-15T11:28:23+09:00
【Ruby】クラスとインスタンス
はじめに
Rubyでは予め定義されている値とは別に、自分で新しい種類の値を作成することができます。
その際「どんな特性を持つのか?」、「どんな動作をするのか?」などの設計図を用意して、作成できます。
新しい種類の値を作成するために必要な概念が、「クラス」と「インスタンス」です。
クラスとは
値の元となるもの。値の共通のルールを定義することができます。
ここで定義するルールとは、共通の「属性」と「処理(メソッド)」です。クラスを使用する利点は、共通の情報をまとめ、個別の情報は各データごとに分けることで、開発・管理・保守が容易になるといったことが挙げられます。
クラスは例えるならば、車の製造における設計図であり、そこから生み出される値が車といえます。
クラスはあくまで設計図ですので、実体がなくそれ単体ではデータとして扱うことができません。クラスの定義は以下のように行います。
class クラス名 # 変数やメソッドの定義 endクラス名は半角英大文字から始めるのがルールです。
(例)User,Groupなどインスタンスとは
クラスを元にして作られるデータのことです。
インスタンスはクラスとは異なり、実体を持つのでデータとして使用することができます。
クラスが車の設計図であるならば、インスタンスはそこから生成される車といえます。インスタンスは、クラスが使用できるnewメソッドを実行することにより生成します。
newメソッドとは
クラスが予め持っているメソッドです。
使用したクラスのインスタンスを生成して返します。使い方は以下のような形です。
#ここではインスタンスを生成し、変数に代入している 変数名 = クラス名.new基本的には上記のように、生成したインスタンスは変数へ代入し、再利用します。
これは、インスタンスを生成したあとからデータを追加したり、メソッドを実行できるようにするためです。以下で実際にクラス名を指定して、インスタンスを生成します
class Car end fire_truck = Car.newこれで「Car」というクラスからインスタンスを生成し、「fire_truck」という変数に代入することができました。
- 投稿日:2020-10-15T03:48:43+09:00
link_toって奥が深いねって話(原因不明)
アプリ開発中投稿ボタンを押したら投稿ページに遷移するようにlink_toで記述をしていた時
<%= link_to "投稿", 'new_photo_path'%>最初はこのように記述しました。
するといつもの
この赤いエラー分が出ました。。仮定
routes.rbがうまく記述できていない
綴りが間違えてるroutes.rbを確認しにきました
routes.rbresources :photos, except: :index root to: 'photos#index'resourcesでindexを除外していること以外に不思議な点はなく
rails routesで確認しても問題はなし…
綴りも間違えていない…
行ったこと
PrefixではなくController#Actionの方を記述した
new_photo GET /photos/new(.:format)index.html.erb<%= link_to "投稿", '/photos/new'%>で解決しました…
追加
@scivola さんからのコメントで原因がわかりました
@scivola さんありがとうございました。
Prefixは''
で囲むと文字列になってしまうようです…
なので自分の場合は文字列として認識されているようです
- 投稿日:2020-10-15T02:01:29+09:00
マイグレーション基礎知識のまとめ rails db:rollbackとカラムの追加/削除
はじめに
【この記事から得られる知識】
・マイグレーションについて
・rails db:rollbackの実行手順
・カラムの追加と削除の実行手順
・カラムがreferences型の場合の追加と削除の実行手順【環境】
・macOS Catalina
・rails 6.0.0
・ruby 2.6.5マイグレーションとは
・テーブルの設計図や仕様書のこと
・データベースにテーブルを作成する際に重要な役割をもっている
-マイグレーションファイルにカラムの型、カラム名、オプションの情報を記述する
-情報を反映させるとテーブルの作成・変更ができるマイグレーションの実行手順
①モデルを作成
②モデル作成時に生成されるマイグレーションファイル(db/migrate/2020~~~~.rb)に必要な情報を記述するdb/migrate/20201014123456_create_address.rbclass CreateAddresses < ActiveRecord::Migration[6.0] def change create_table :addresses do |t| # t.カラムの型 :カラム名, オプション t.string :postal_code, null: false t.string :city, null: false t.string :address_line, null: false t.string :phone_number, null: false t.references :order, null: false, foreing_key: true t.timestamps end end end③記述したテーブルのカラムを反映させるために作成中のアプリケーションのディレクトリにいることを確認した後ターミナルでrails db:migrateを実行
% rails db:migrate
④ターミナルに以下のような記述があれば成功!
== 20XXXXXXXXXXXX CreateAddresses: migrating ====================================== -- create_table(:addresses) -> 0.0395s == 20XXXXXXXXXXXX CreatePosts: migrated (0.0396s) =============================念のためsequelproでも記述した情報が表示されていれるか確認する
※情報が反映されていない場合は更新ボタンをクリックする
せっかくrails db:migrateしたのにテーブルにミスがあった!
「どうしよう、、、」
「マイグレーションを編集したいっ!」ていうときありますよね。しかし、一度実行すると再度実行できない仕組みになっています。
なぜかというと設計を履歴として残しあとでどのような変更をしたか確認できるようにするためです。もしスペルミスでカラム名を変更したい場合であればわざわざ履歴に変更を残したくないですよね。
その場合は
rails db:rollback コマンド
を使いましょう。(反映済みの情報を差し戻すことができるため変更の履歴が残りません。)
それ以外の場合はカラムの追加/削除用のマイグレーションファイルを作成して変更を行いましょう。(新たにファイルを作成して変更をするため履歴が残ります。)以下でこれらの説明をしたいと思います。
rails db:rollback 実行手順①~⑥
①
rails db:migrate:statusコマンド
でマイグレーションファイルの状況を確認% rails db:migrate:status
・実行するとマイグレーションの履歴が表示され、statusがupとdownで状況が表示される
・upは実行済み、downは修正可能の状態を意味する# rails db:migrate:stauts 実行結果 database: アプリ名_development Status Migration ID Migration Name -------------------------------------------------- up 20201001015223 Create orders up 20201001092756 Create addresses up 20201014023427 Add id to addresses up 20201014030100 Add id to orders②
rails db:rollback
を実行してup(実行済み)をdown(修正可能)にする% rails db:rollback
③もう一度
rails db:migrate:status
を実行しマイグレーションファイルの状況を確認するdatabase: アプリ名_development Status Migration ID Migration Name -------------------------------------------------- up 20201001015223 Create orders up 20201001092756 Create addresses up 20201014023427 Add id to addresses down 20201014030100 Add id to orders④変更したいマイグレーションファイルのstatusがdownであることが確認できると今回の場合db/migrate/2020101430100_~~.rbのファイルを修正する
⑤rails db:migrate
を実行し修正内容を反映させる% rails db:migrate
⑥念のためsequelproでも記述した情報が表示されていれるか確認する
※情報が反映されていない場合は更新ボタンをクリックする【補足情報】
任意のマイグレーションファイルをrollbackしdownの状態にしたい場合は
rails db:rollback STEP=数値(戻りたい箇所が下から数えて何番目か)
というふうに記述し実行する
※一番下を1とする# 下から2番目をrollbackしたい場合 % rails db:rollback STEP=2statusを確認すると下から2番目までdownになっていることが確認できる
database: アプリ名_development Status Migration ID Migration Name -------------------------------------------------- up 20201001015223 Create orders up 20201001092756 Create addresses down 20201014023427 Add id to addresses down 20201014030100 Add id to orders後は同じようにマイグレーションファイルを修正し
rails db:migrate
を実行するカラムの追加/削除 実行手順(パターン1, 2)
最初に前提の知識としてカラムの追加は
add_column
カラムの削除はremove_column
と記述する# カラムの追加 add_column :users, :first_name, :string # カラムの削除 remove_column :users, :last_name, :stringパターン1 : 順番に記述する方法
①
rail g migration ファイル名
を実行
ファイル名はAddカラム名To追加先のテーブル名
とする(ファイル名は任意のものでもいいが、Add~To~が後から見たときにわかりやすく定着したファイル名のつけ方になっている)# nameカラムをUsersテーブルに追加する場合 % rails g migration AddNameToUsers生成されるファイルの中身
db/migrate/20200000000000_add_names_to_users.rbclass AddNamesToUsers < ActiveRecord::Migration[6.0] def change end end②新しく生成されたマイグレーションファイルに情報を記述する
db/migrate/20200000000000_add_names_to_users.rbclass AddNamesToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :first_name, :string add_column :users, :last_name, :string end end③
rails db:migrate
を実行する% rails db:migrate
パターン2 : ターミナルにまとめて記述する方法
①
rail g migration ファイル名 追加するカラム名:型
を実行# 追加するカラムの詳細情報までまとめ記述する % rails g migration AddNameToUsers first_name:string last_name:string生成されるファイルの中身(ファイルの中身が記述された状態でマイグレーションファイルが生成)
db/migrate/20200000000000_add_names_to_users.rbclass AddNamesToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :first_name, :string add_column :users, :last_name, :string end end②
rails db:migrate
を実行する% rails db:migrate
references型カラムの追加/削除 実行手順
状況:Ordersテーブルに外部キーとしてaddress_idを追加する
①
rails g migration ファイル名
を実行する# address_idカラムをOrdersテーブルに追加する場合 % rails g migration AddIdToOrders②生成されたファイルに記述する
db/migrate/20201014000000_add_id_to_orders.rbclass AddIdToOrders < ActiveRecord::Migration[6.0] def change # 追加 add_reference :orders, :address, foreign_key: true # 削除 remove_reference :orders, :address, foreign_key: true end end追加のポイント
・add_reference
であること
・foreign_key: true
を記述すること(必要な場合のみ)
削除のポイント
・remove_reference
であること③
rails db:migrate
を実行する% rails db:migrate
解説は以上です!!
想像より長くなってしまいましたがこの記事がお役に立てると幸いです。
慣れると簡単なのでぜひ習得してスムーズに開発が進められるようにしましょう!
それでは、最後までご覧いただきありがとうございました。参考
・https://qiita.com/kurawo___D/items/e3694f7a870a1cc4738e
・https://freesworder.net/rails-column-add-remove/
・https://gist.github.com/seak0503/84bfa6b37a0a6961c334
- 投稿日:2020-10-15T00:36:35+09:00
Git 簡単に変更前の状態に戻す方法(コミット前)
コミット前の変更点をターミナルを使わずに変更する
他のブランチに移動するだけ!
この方法が最も簡単に変更前に戻す方法なのですが、他の事例に当てはまる場合は下記の方の記事を参考にするといいですよ!
https://qiita.com/tani-shi/items/3419600447292abf6c79
@tani-shi現場からは以上です!