seedにデータを入れようとしたらTypeMismatchと言うエラーが出た時の解決
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回はseeds.rbにデータを用意しようとしたらエラーにハマった時の解決の流れをアウトプットしようと思います。
状況
PFでクイズアプリを作成していました。
テーブルは下記の状態です。
scoreテーブル
contentカラム•••問題文を格納
score_answerテーブル
contentカラム•••解答が格納
scoreカラム•••点数が格納
この2つのテーブルは1対多の関係です。
seeds.rbに記述したデータ
今回のエラー
ActiveRecord::AssociationTypeMismatch: Score(#70277478931200) expected, got 0 which is an instance of Integer(#70277413551180)
思考手順
①AssociationTypeMismatchと出ていたので関連づけがうまくいってないと言う点にあ
たりをつける
②とりあえずエラー文をぐぐります。
すると「渡ってきた外部キーが違うよ」と言うような記述を発見。あたりは外してな
かったのでこのまま進みます。
③エラー文を見直すと、Score(#70277478931200) expected, got 0 which is an
instance of Integerと書いてあり予期していた値と違うものがきたと読み取りました。
④そもそも私はscore_idにid=1を入れたいのに0がきてるよと言われています。
そこで気づきました。アソシエーションのscoreとカラムのscoreがコンフリクト?し
ているのではと。
解決
まずscoreカラムをrescoreカラムに修正します。
その後、seeds.rbのscoreもrescoreに変更します。
ここまできたら最後にsaveしてrails db:seedでデータを作成します。
うまくいきました。
最後に
今回私の確認が甘くカラムとモデルの名前を同じものにしてしまいました。
通常は問題ないのかもしれませんがリレーションをいれると値がかぶってしまっていたようです。
でもそのおかげで初めて会うエラーを知り、記事も少なかったので残しました。
今後も都度残していければと思います。
Vue.jsのaxiosを使った時になんだこれはとなった話
プログラミングを本格的にスタートして5ヶ月目に入りましたさかもとです。
今回はVue.jsを学んでいる時にAPIから値をひっぱってくるためにaxiosを使ってこんがらがってしまったという話をアウトプットしようと思います。
前提
今回はRailsにVue.js導入している時に個人的に詰まったものをまとめています。
axiosって?
axiosはgetやpostなどのhttpリクエストを使ってサーバからデータを取得や更新を行うことができるようになる
axiosの設定
①axiosを使用する場合初めにインストールをしなくてはならない。
今回はyarnでインストールしようと思う
```
$ yarn add axios
```
導入の方法に関しては
https://github.com/axios/axios
こちらのaxiosのgithubを参照した。
②インストールが終了したら次は設定をしなくてはならない。
初めにApplicationControllerに下記を記述しCSRFを無効化します。
```
protect_from_forgery with: :null_session
```
これをしないとpostを行うことができないので必須です。
CSRF(シーサーフ)に関しては参考文献に記事をはるので都度参照。
③今回、メインのJSファイルをコードで汚したくなかったので別ファイル
を作りそこからインポートしてくる形を取りました。
```
import axios from 'axios'
// ここでaxiosを適用するためにインポートしています。//
const axiosInstance = axios.create({
baseURL: ' api ' //ベースのURLはrutesで設定したapiを適用//
})
export defoult axiosInstance
//export defoltをつけることでこのファイルで定義したメソッドを外部で使用することができる
```
⑤続いて④で設定したaxiosファイルをmainのjsファイルで呼び出し全 体でaxiosが使用できるように設定していきます。
```
import axios from '../axios'
//④で設定したファイルを適用します//
Vue.prototype.$axios = axios
//上で適用したものをprototypeに入れ$axiosを全体で使えるようにします//
```
prototypeに入れることで衝突を避けることができます。
この衝突がなんなのかに関しては参照記事を読む。
⑥最後に⑤で定義した$axios、ライフサイクルフックとメソッドを使 ってAPI通信を実行していきます。
```
:
created() {
this.fTasks() ;
},
methods: {
fTasks() {
this.$axios.get("tasks")
.then( res => this.tasks = res.data )
.catch( err => console.log( err.status ));
}
}
:
```
ライフサイクルフックに関しても参考記事を参照
初めにcreatedでインスタンスが初期化された段階でfTasksが実行されます。
その内容はmethodsに表記されており発火した際
$axios.get("tasks")でgetリクエストを送っています。
そのresponseとして空のtasksに送られてきたdataが代入されます。
これでブラウザに表示されるようになるわけです。
最後に
axiosについては私もまだまだ未経験なので今後も雑にアウトプットしていこうと思います。
読んでいただきありがとうございました。
参考記事
ポリモーフィック関連でギブアップした話
プログラミングを本格的にスタートして4ヶ月目に入りましたさかもとです。
今回はポリモーフィック関連が定義されていることに気づかず、愚直に既存モデルから値を引っ張ってこようとして泣いたという話をアウトプットしようと思います。
ポリモーフィック関連って?
Railsガイドには一つの関連付けで複数のモデルと関連を持つことができる。と記述されています。
実装方法は下記のように書きます。
=================================================
例)Userモデルにadminとemployeeの二つのモデルを関連付けたい
userモデル
```
belongs_to :position, polymorphic: true
```
adminモデル
```
has_many :users, as: :position
```
employeeモデル
```
has_many :users, as: :position
```
==================================================
userモデルでポリモーフィックを定義しています。
今回userモデルに複数のadminモデルとemployeeモデルが派生していると仮定して、userモデルに対してhas_manyで定義されています。
as: :positionとしているのは@user.positionと呼び出すとそのuserのpositionを呼び出すことができます。
逆に@employee.positionと定義すればuserモデルのインスタンスを取得することも可能です。
どういう時に使うの?
私が1番疑問に思ったのはここでした。正直、今までの関連づけでよくないか?と。
しかし場合によってはポリモーフィックはとても便利です。
それはどんな時か
```
一つのモデルの中で権限や役割、メソッドが派生した場合
```
です。
?????って感じだと思います。
先ほどの例で説明してみましょう。
=====================================================
Userモデルの中にadminとemployeeが派生していました。
このadminとemployeeってどんなモデルでしょう。
admin = 管理者権限が付与されている
employee = 一般ユーザー
このような役割です。
しかし、どちらのモデルもuserモデルの情報は変わりません。
あくまで1人のUserがどちらのpositionにいるのかという状態です。
このように情報を共有しながら一部だけ違う場合は通常の関連付けよりポリモーフィックを使用する方が実装は簡単にすみます。
=====================================================
まとめ
モデルの実装は奥が深くテーブルが増えれば増えるほど複雑になっていきます。
こう言った実装方法を覚えていきながら進んで行こうと思います。
参考記事
validatesで数値の以上以下指定でつまった話
プログラミングを本格的にスタートして4ヶ月目に入りましたさかもとです。
今回はint属性の〜以上〜以下のバリデーションがかからなかった!という話をアウトプットしようと思います。
成り行き
課題
「int属性のwideカラムを追加し、100〜200のみ入力可能になるようバリデーションを設定してください」
私
「余裕ですね。validates :width, length { minimum: 100, maximum: 200 } これで100~200の間の数値しか受け付けないはず」
ブラウザで確認
。。。バリデーションが全くかからない
私
「????????」
原因
今回私がこのような状態になった理由として数値の有無はlength{ minimum: maximum}で図るものだと認識していたからでした。
解決
一つ一つ整理していきます。
①length{ minimum: maximum}は数値の有無を図るものではない
これは文字数の制限をかけるvalidatesです。つまりint属性のカラムに対して働くものではないということ。string型やtext型に働きかけるものです。
②数値の最低最高を定めるバリデーション
numericality: {~} : 属性に対して数値のみ使われているか確認します。
デフォルトでは整数値、少数関係なく作用します。
greater_than_or_equal_to : その数値を含むないしそれ以上の値であるか検証。
less_than_or_equal_to : その数値を含むないしそれ以下の値であるかを検証。
greater_than : その数値より大きいかを検証(その数値は含まない)
less_than : その数値より小さいかを検証(その数値は含まない)
結果
以上のことから今回は
```
validates :width, numericality: { greater_than_or_equal_to : 100,less_than_or_equal_to: 200 }
```
このように記述してあげるのが正しい方法でした。
まとめ
他にも数値のバリデーションに関してはいくつか種類があったので下記URLから随時確認していこうと思います。
参考記事
cronとwheneverで定期実行を行う話
プログラミングを本格的にスタートして3ヶ月目に入りましたさかもとです。
今回はcronとwheneverについて!という話をアウトプットしようと思います。
cronって?
cronとはlinuxのOS上にあり、定期実行させたい場合にブラウザで動作しなくても裏で自動で走ってくれる(デーモンプロセス)機能のことをいいます。
wheneverって?
wheneverとは「1分おきにデータを更新したい!」とか「1日おきに更新したい!」などの定期実行の設定を簡単にかけるgemです。
この2つを組み合わせてwheneverで設定したものをcronで動かす。という流れを作ります。
実装手順
①gemのインストール
```
gem 'whenever' , require: false
```
bundleを忘れずに
②設定ファイルの作成
```
bundle exec wheneverize .
```
config/schedule.rbというファイルが作成される。
③wheneverファイル(schedule.rb)に設定を記述していこう
初めに大切なことはRailsと同期させるために環境変数をセットすることです。
こうすることにより実際に実行されたかをログを頼りに確認することができます。
④実際に実行されるタスクを記載
ここに関しては今回具体的な動作を書くことは致しません。
しかし書き方には注意してください。
例えば10分おきに実行されるプログラムが作りたいとしましょう。
その場合の記述方法は
```
every 10.minutes do
:
end
```
このように記載しましょう。こうすることで10分おきに稼働します。
ここまでがwheneverの設定方法です。今度はこれを実行させるためにcronに反映させていこうと思います。
⑤設定内容にエラーなどがないかの確認
```
bundle exec whenever
```
⑥設定した内容をcronに反映
```
bundle exec whenever --update-crontab
```
これで反映は完了です。
あとは実際にデータを作成し更新され、ログが残るかを確認すれば終了です。
参考記事
Railsでwheneverを使ってcronを設定する - Qiita
【Railsで定期実行】wheneverの使い方紹介 | shin>>media
パンくず作成の話
プログラミングを本格的にスタートして3ヶ月目に入りましたさかもとです。
今回はパンくずを作成してみよう!という話をアウトプットしようと思います。
パンくずって?
これがパンくずです。HRとかで画面の端についてるやつです。現在HRのどのあたりにいるかが一発でわかり遷移を1クリックでできるとても便利な機能です。
実装方法
①インストール
gem ' gretel '
bundle install
②ファイルの作成
rails generate gretel:install
(これにより config/breadcrumbs.rb が作成される)
③定義
②のファイルにデータを記述。今回は例として
ダッシュボード画面 → ユーザー一覧画面 → ユーザー編集画面
この順番で遷移していくページのパンくずを作成していきます。
```
crumb :dashboard do
link ' ダッシュボード ' , dashboard_path
end
crumb : users do
link ' ユーザー ' , users_path
parent : dashboard
end
crumb : edit_user do | user |
link ' ユーザー編集 ' , edit_user_path( user )
parent : users
end
```
これでパンくずの定義が完了しました。
1行目→crumbでパンくずを定義
2行目→パンくずに表示する名前とリンク先のパスを定義
3行目→parentで親となるパンくずを定義
これでひとかたまりになります。
④viewに記述
viewに記述し実際にブラウザに表示されるようにしていきます。
今回はユーザーとユーザー編集のみ記載していきます。
```
user.html.erb
:
<% breadcrumb : users_path %>
```
```
edit.html.erb
:
<% breadcrumb : edit_user_path, @user %>
```
以上で実装は完了です。
viewに関しては難しいところはないように思いますが<%= %>で表記しないこと。
変数はインスタンス変数で定義すること。
ここは注意が必要です。
最後に
今後も学びを自分が見返せるようにアウトプットしていこうと思います。
Seed_fuって何?って話
プログラミングを本格的にスタートして3ヶ月目に入りましたさかもとです。
今回はseed_fuを使った際にデータが作成されない!ってなったのでseed_fuの話をアウトプットしようと思います。
seed_fuって何?
初期データをデータベースに作成したいときに使うgem。
seedより柔軟で扱いやすい。
インストール
gem ' seed_fu '
bundle
ファイルの作成
db/fixtures以下に環境別にフォルダを作成後、作成したいmodel別にファイルを作成。
データの記述
seedは「種」という意味がありますが今回も作成するもととなるデータを作成します。
今回はpuroduction環境のuserモデルを作成していこうと思います。
production/users.rbにモデルの情報を記入していきます。
```
User.seed(
{ id: 1, name: 'user1', crypted_password: 'user1_password', role: :admin }
)
```
このようにカラムにあった内容を記述します。
現段階では記述しただけで実際に作成はされていません。
データの作成
```
rake db:seed_fu
```
このコマンドでデータが実行されます。
しかし気をつけなくてはいけない点があります。
今この段階でproduction環境のデータは作成されたかもしれませんが他の環境のデータが作成されたかはわかりません。
自分が狙ったファイルのデータが実行できるように作成する場合はファイルを指定してあげると良いです。
```
rake db:seed_fu FIXTURE_PATH=(ファイルの場所)
```
テスト実行時の記述
Rspecなどの自動テストはテスト毎にデータがクリーンな状態になるように設定されていると思います。
しかしseed_fuを使う場合はマスターデータとしてテスト前にすでにデータが作成されている状態にしておきたいです。
そんな時はseedが自動で実行されてからテストが走り出すように設定しましょう。
```
rails_helper.rb
:
:
RSpec.configure do |config|
config.before :suite do
SeedFu.seed
end
end
```
これで完了です。