rails初心者というより、rubyすら初心者。
意外とハマった云々というより普通にハマったことを書いていく。
同じことでつまづいた人いたら共感して!
ハマったこと
- ruby
- rubocopが機能しない
- case~文
- rails
- resourceとresoucesを間違える
- ルーティングのprefixがわからない
- Associationsが便利だったということ
- なぞのLoadError
ruby
rubyというカテゴリで良いのだろうか?
細かいところですが、地味に時間かかった部分を書いておきます。
rubocopが機能しない
ale使って非同期Lintしたかったという話。
bundleでgemの管理をプロジェクト毎にした場合、bundle execで動くrubocopが上手いこと起動してくれません。
5分くらい色々ググりはしたけど出てこなかったので、:h rubocop
(エディタがvimなので)で調べてみた。
一発で出ましたね。
初めからそうしとけばよかった。。。
g:ale_ruby_rubocop_executable *g:ale_ruby_rubocop_executable*
*b:ale_ruby_rubocop_executable*
Type: String
Default: 'rubocop'
Override the invoked rubocop binary. Set this to 'bundle' to invoke
'bundle exec rubocop'.
be rubocop使うためには'bundle'を設定しなさいってよ。
なんで、設定ファイルにlet g:ale_ruby_rubocop_executable = 'bundle'
書いたらちゃんとlintしてくれました。
case文
erbファイルでcase使う話です。
まじハマった。
構文間違って覚えてるのかと思って、普通にrubyで書いてみたら上手く行くし。
つか、実際使う必要なかったので諦めようかと思ったけど、いざ使うってなった時困るから頑張ろうと諦めなかった。
調べてもあんま出てこなかったけど解決しました。
<% # NG %>
<% case パラメータ %>
<% when 定数1 %> << syntax error, unexpected tIDENTIFIER, expecting when
何か表示 << syntax error, unexpected when, expecting end
<% when 定数2 %>
何か表示 << syntax error, unexpected when, expecting end-of-input
<% else %>
何か表示
<% end %>
これではダメです。
rubocopは上の3つのエラーを出してきます。
うん。おしえてくれてありがとおおお。
rubocop言葉足りなくないっすか?
<% # OK %>
<% case パラメータ # ここのと下の部分を繋げたコードが正しい
when 定数1 %>
何か表示
<% when 定数2 %>
何か表示
<% else %>
何か表示
<% end %>
rails
アホを晒す。
resourceとresoucesを間違える
例のごとくprogateではscaffoldを使わないでルーティングを直書きして教えてくれてたので
(config/routes.rb) get 'hoge/index' => 'hoge#index'
みたいに直書きしてました。
resources使いましょうとのことなので、resources :hoge
みたいにすれば終わりだった。
はずだった。
URLにidの情報ほしいなーって思ってたのですが、resources使えばそれも準備してくれるとのこと。
便利だなあ。よっしゃ。書き換えるで。
Rails.application.routes.draw do
resource :hoge
end
# -------------------------------------------------- #
# terminalでbe rails routes | grep hoge
# -------------------------------------------------- #
# new_hoge GET /hoge/new(.:format) hoges#new
# edit_hoge GET /hoge/edit(.:format) hoges#edit
# hoge GET /hoge(.:format) hoges#show
# PATCH /hoge(.:format) hoges#update
# PUT /hoge(.:format) hoges#update
# DELETE /hoge(.:format) hoges#destroy
# POST /hoge(.:format) hoges#create
は?idないやんけ。(憤怒)
まあ、もし同じエラーになった人、もしくは知ってる人知ってた人なら気付くでしょうけどresource's'が正しい。
というか、resourceというのも存在してるんですね。
Rails.application.routes.draw do
resources :hoge # resource => resource's'へ変更
end
# -------------------------------------------------- #
# terminalでbe rails routes | grep hoge
# -------------------------------------------------- #
# hoge_index GET /hoge(.:format) hoge#index
# POST /hoge(.:format) hoge#create
# new_hoge GET /hoge/new(.:format) hoge#new
# edit_hoge GET /hoge/:id/edit(.:format) hoge#edit
# hoge GET /hoge/:id(.:format) hoge#show
# PATCH /hoge/:id(.:format) hoge#update
# PUT /hoge/:id(.:format) hoge#update
# DELETE /hoge/:id(.:format) hoge#destroy
まじくそ。
ルーティングのprefixがわからない
form_withとかで、urlを/hoge/index
みたいに直書きしてました。
というか上でもそうだけど、直書きとかやってる時点でなんかないんかなあって気づいて調べろよって話でもあるんだけど。
railsではPrefix_pathでURLを作ってくれて、このメソッドを使いましょうとのことでした。
よし、書き換えるか。
GET /hoge を hoge_indexへ変更
POST /hogeは...あれ?Prefixなくね?
これ。
たぶん当たり前のことすぎて検索しても出てこない。
「rails prefix」、 「rails prefix どれ」
Progateで見落としてたのか?と思って戻ってもかいてない。。。
時間は過ぎていく。
お、俺が悪いってのか…?俺は…俺は悪くねえぞ。だって仙人が言ったんだ…そうだ、ひつじ仙人がやれって!
こんなことになるなんて知らなかった!誰も教えてくんなかっただろっ!
はい。
こんな感じで参考記事を見つけました。
同じ気持ちになっている人1がいてすごく嬉しいんですけど、タイトルを考えて欲しかった。
見つけにくい。
Prefix | Verb | URI Pattern | URI Pattern |
---|---|---|---|
hoge_index | GET | /hoge(.:format) | hoge#index |
hoge_index(ここ空白) | POST | /hoge(.:format) | hoge#create |
new_hoge | GET | /hoge/new(.:format) | hoge#new |
edit_hoge | GET | /hoge/:id/edit(.:format) | hoge#edit |
hoge | GET | /hoge/:id(.:format) | hoge#show |
hoge (ここ空白) | PATCH | /hoge/:id(.:format) | hoge#update |
hoge (ここ空白) | PUT | /hoge/:id(.:format) | hoge#update |
hoge (ここ空白) | DELETE | /hoge/:id(.:format) | hoge#destroy |
一番上に書かれているPrefixを新しいPrefixが出てくるまで参照し続ける書き方がrails routesで出力されます。
Associationsが便利だったということ
これはつまづいたというより、純粋にAssociationsが便利だなって思ったことです。
例えば
posts (1 : 多) comments
の構造があったとして、それぞれのモデルクラスで
has_many :comments
belongs_to :posts
と記述すると、
@post = Post.find(params[:id])
@comments = Comments.where(post_id: @post)
とかしなくて、
@post = Post.find(params[:id])
# @comments = Comments.where(post_id: @post)は
# @post.commentsと等価
でいける。
なんかよくわかってないけどActiveRecordすげえ。
なぞのLoadError
Associationsでハマった?というのかわからんけど、引っかかったのはこっち。
前の日まで動いていたコードが次の日には動かなくなっていたーーー!!
エラーの内容はこれ。
> Unable to autoload constant Comment,
> expected [Project root]/app/controllers/concerns/comment.rb to define it
<% @post.comments.each do |comment| %> <-- ここエラーですよ。みたいな
Commentっていう定数が見つからんので、concerns/comment.rb
で定義しろみたいな。
concernsで共通処理書こうとして、とりあえずcomment.rbでいっかーみたいにしたのがだめらしい。
らしいというのはよくわかっていなから。
名前被ってるとダメみたいなので、試しに、comment_common.rbみたいに名前変えたらうまくいった。
おわりに
多分もっとあったけど、思い出せる範囲でこんなもん。
以上!
-
[RailsのRoutingの省略まじでおこ] (https://qiita.com/makua/items/124a13d0dbb300a13f19)
全部丁寧に書くとこんな感じ。 ↩