Rails ルーティングのPrefixの空白、検索力

今日改めて思ったことがある。

検索力はとても大事だ。

 

 

Prefix     verb   URIパターン                   Controller#Action
tweets GET /tweets(.:format) tweets#index POST /tweets(.:format) tweets#create new_tweet GET /tweets/new(.:format) tweets#new edit_tweet GET /tweets/:id/edit(.:format) tweets#edit t¥weet GET /tweets/:id(.:format)
tweets#show

 

tweets#create のPrefix の空白について。

この空白はパスが通ってないから空白なのだと思い、パスを通すための方法を延々検索したていた。1時間以上たった時、ふと『Prefix 空白』と入れると一発で出てきた。

これは上と同じだから省略されているだけでつまりは下記のようになっている。

 

Prefix     verb   URIパターン                   Controller#Action
tweets GET /tweets(.:format) tweets#index tweets POST /tweets(.:format) tweets#create new_tweet GET /tweets/new(.:format) tweets#new edit_tweet GET /tweets/:id/edit(.:format) tweets#edit t¥weet GET /tweets/:id(.:format)
tweets#show

 

 

 

 

また今日ではないが、Rails で gem をインストールするために bundle install コマンドを打つとエラーが出てきて、最後の文が下記のようだった。

 

An error occurred while installing puma (4.3.3), and Bundler cannot

continue.

Make sure that `gem install puma -v '4.3.3' --source 'https://rubygems.org/'`

succeeds before bundling.

 

つまり gem の puma のバージョン 4.3.3 をインストールしないとエラー起きて続けられないよ、というエラーだ。

しっかりこの文を読んで解決すれば良かったのだろうが、その時は上のエラー文を丸々検索して解決方法を得ようとした。

結果、どういう経緯だったか忘れたが、時間をかけXcodeをアップデートすれば良いというような記述を見つけ、さらに時間をかけてアップデートしたところ、またエラーが起きた。

 

結局、Gemfileのgemの記述を変えることですぐに解決したのだが、今日ふとこれを思い出した。(ちなみに puma v4.3.6 をインストールすると良いようだ)

 

無闇に検索した結果、時間をかけて意味のないことをしてしまった。

 

 

これからは検索するときには検索力という言葉を頭になんとなくではなく根拠を持って検索していきたい。 

明日も頑張ろう。

 

 

:(コロン)と,(カンマ)

コロンとカンマ、rubyの記述の中にかなり出てくるが、文字の右についたり左についたりとどんな法則でついているのだろうか。

調べてみた限りではこんな感じだ。

 

<コロン> 

①シンボルとして記述される

 

"name"はシンボルにすると :name

またハッシュの記述でnameをキーとすると

{ :name => "Taro"} は {name: Taro} と記載される

シンボルは使う場面で文字の右左と場所が変わる。

 

ちなみにわかりにくいが

params.require(:room).permit(:name, user_ids: [])

の :room もroom というキーを指している

 

 

②メソッドの後にはつかない。

 

例えばコントローラーのピンクのbefor_actionメソッドやモデルでのアソシエーションのメソッドには付かず、黄色のconfigure_permitted_parameters, devise_controller? メソッドでは前に付いている

before_action :configure_permitted_parameters, if: :devise_controller? 

 

belongs_to :user

 

 

③オプションの後ろに着く

 

例えば if や model ,locla などのオプション

before_action :configure_permitted_parameters, if: :devise_controller? 

 

<%= form_with model: current_user, local: true do |f|%>
 
 
④アクション名の前につく
 
resources :users, only: :show
<%= link_to '削除', tweet_path(tweet.id), method: :delete %>
 
 
 
⑤△△ 対 〇〇 の関係性の場合は前につく?
 
belongs_to :user

validates :content

 

これに関してはよくわからなかったので推察してみた。

上記の記述がmessage.rb というMessageモデルに記述されているとする。

 

アソシエーションでは :user は Messageモデル 対 Userモデル
バリデーションでは :content は Messageモデル 対 contentカラム


のようにメソッドの後ろに記述しているものは△△対〇〇の関係性のがあることを示すためコロンをつけている。

 

 

ここまで考えてコロンなんて使っていないだろうけれど気になる。

 

 

<カンマ>

 

これは application.html.erb の記述の一部

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>

 

おそらくHTMLの記述だとカンマは使用せず、Rubyの記述だとカンマが必要という認識だと思う。

 

 

というという訳で考察終わり。

今日も頑張ろう。

 

 

 

===>後書き

⑤についてはRailsのメソッドにはシンボルを渡すメソッドがあるということらしい。

つまり、シンボルというのはただの文字列をコロンをつけて記述したものではないということ。次はシンボルについて調べてみようかな

idと『.』ドット

最近記述式の中でよく分からなかったのがこういった記述のidについて

 

<% if user_signed_in? && current_user.id == tweet.user_id %>

 

<%= link_to '編集', edit_tweet_path(tweet.id), method: :get %>

 

最初はなんで左は user.id で右は user_id なのか、とかpathの後ろの tweet.id ってどういう時につけるのかが疑問だった。

 

しかし冷静に一つ一つ考えると解決できた。

 

①のcurrent_user.id == tweet.user_idに関してはまず

current_user は、現在ログインしているユーザーの情報を取得するメソッド

なので current_user.id は『現在ログインしているユーザーのid』ということ。

次に

tweet.user_id tweetというテーブルの中の user_id というカラムのデータということ(つまり『tweetテーブルレコードのuser_id』)。

つまり、current_user.id == tweet.user_id 『現在ログインしているユーザーのid』が『tweetテーブルレコードのuser_id』と等しい ということになる。

 

ここで解ったのは『.』ドットが鍵だということ。

 

 

②のedit_tweet_path(tweet.id)

についてはターミナルの rails routes コマンドにて確認すると

Prefix     verb   URIパターン                   Controller#Action
tweets GET /tweets(.:format) tweets#index POST /tweets(.:format) tweets#create new_tweet GET /tweets/new(.:format) tweets#new edit_tweet GET /tweets/:id/edit(.:format) tweets#edit t¥weet GET /tweets/:id(.:format)
tweets#show

このようになっている。

URIパターンの /tweets/:id/edit(.:format) を見るとこの edit_tweetパスは tweet の id が紐ついている。

つまり

edit_tweet_path(tweet.idtweet の id』に紐ついた 『edit_tweet_pathということになる。

 

つまり、rails routes コマンドのURIパターンを見ればわかるということだ。

 

また明日も頑張ろう。

 

 

 

 

undefined method エラー解消

NoMethodError in MessagesController#create

undefined method `message' for #<Room:0x00007fa9065717a8>

def create
@room = Room.find(params[:room_id])
@message = @room.message.new(message_params)
@message.save
end
{"authenticity_token"=>"kK5hHuNqFM72OK/UKel8gZY460pFfn1ZBkAKXsQhjJti/OWmvTaS3nojQeS0MbaFrDogz0BfoToEk7cDKh9vTQ==", "message"=>{"content"=>"さdkbkjsd"}, "commit"=>"送信", "room_id"=>"1"}


 
エラー。
今回が今までで一番時間かかったなぁ。
 考えた手順は以下の通り。
 
①ビューはコントローラーへパラムス送信してる
 →"message"=>{"content"=>"さdkbkjsd"}, "commit"=>"送信", "room_id"=>"1"}
 
②コントローラー記述に間違いはないか
 →何度も何度も見直し、messagesはテーブル名ということで "message"→"messages" に変更。他は間違いなし。
 
③これが定義されてない…messages が孤立してる?
関係性…
アソシエーション!?
 
models/room.rb
class Room < ApplicationRecord
has_many :room_users
has_many :users, through: :room_users
has_many :rooms

validates :name, presence: true
end
  
というわけでroomモデルファイルに原因が見つかった。
"has_many :rooms" → "has_many :messages"
 
 
たいしたエラーではないのだろうけれど、自分で解決すると他のことも一緒に調べるから勉強になる。
 
ちなみに "belongs_to" の場合は後ろの文字が単数形になる。
 
 
でも時間かかっちゃうからエラーが出たときだけ、精神と時の部屋に篭りたい。

Ruby on Rails シングルクォーテーションとダブルクォーテーションの謎

Rubyにおいて文字列を表すのにシングルクォーテーション( ' )やダブルクォーテーション( " )を使って囲む。

 

シングルクォーテーション( ' )で囲むと囲ったものは全てが文字列と認識されて、そのまま出力される。

 

 

food = '牛丼'
drink = 'コーラ'

puts '私は#{food}が好きです。n/飲み物は#{drink}が好きです。'

<出力結果>

私は#{food}が好きです。n/飲み物は#{drink}が好きです。

 

 

ダブルクォーテーション( " )で囲むと、特殊文字や式展開がある場合は行ってくれる。

 

food = "牛丼"
drink = "コーラ"

puts "私は#{food}が好きです。\n飲み物は#{drink}が好きです。"

<出力結果>

私は牛丼が好きです。

飲み物はコーラが好きです。

 

 

しかし、Ruby on Railsのテストコードにおいて謎が出てきた。

 

結合テストコードで下記のような記述があり、これは正解。

expect(page).to have_selector ".content_post[style='background-image: url(#{@tweet_image});']"

 

しかしなぜか式展開があるにもかかわらずシングルクォーテーションが使われている。

background-image: url(#{@tweet_image}); '

 

ちなみにこの部分、シングルクォテーションをダブルクォーテーションに書き換えるとエラーが起きる。

 

細かいところばかりが気になってしまう悪い病気だ。

調べてもわからないから今日は諦めて明日また調べよう。

 

11/12 追加記載

すっかり今日までブログに追記するの忘れてた。

これは単純で

 

expect(page).to have_selector ".content_post[style="background-image: url(#{@tweet_image});"]"

 もしこうしちゃうと

".content_post[style="    "]"

ダブルクォーテーションで囲まれた部分が上記のように認識されてしまうから。

 

ちなみに

expect(page).to have_selector ".content_post[style='background-image: url(#{@tweet_image});']"

 

これは一度

".content_post[style='background-image: url(#{@tweet_image});']"

このようにダブルクォーテーションで囲まれてるから

 

'background-image: url(#{@tweet_image});'

この部分がシングルクォテーションで囲まれていようと#{@tweet_image}の式展開はできるという理屈みたい

 

以上

Railsのform_withについて

今回はヘルパーメソッドで使われるform_withの中の記述。

なんでmodelのみの時とurlと一緒の時があるのか。

実は省略されているか、されていないかの違いらしい。

 

<1><%= form_with(model: @tweet, local: true) do |form| %>

 

これはある写真投稿アプリの写真を新規投稿する時の画面におけるビューの記述

  

本来は url が記載されているはずではあるが、なぜか省略できる。

理由は不明。いずれ調べたい。

 

そしてデータベースへ投稿フォームに記述した内容が保存される必要があるのでmodelを使っている、ということらしい。

まず、form_withが実行された時、渡されたインスタンスの中身が空かそうではないかをRuby on Rails君が識別する。

今回は新規投稿なので、paramsが空。

よってRails君の自動識別で空の時の反応がなされてcreateアクションへ、となる。

もしもインスタンスの中に情報が入っていた場合は、投稿の編集ということになるので、updateへ繋がる。

(ちなみに新規投稿と投稿編集では同じ記述になっている)

 

 

<2> <%= form_with model:@user, url: user_registration_path, id:'new_user', class:'new_user'', local: true do |form| %>

 

これはある写真投稿アプリの新規ユーザー登録画面のビューの記述

 

ここでも、登録フォームに記述した内容がデータベースに保存される必要があるのでmodelを使っている。

そしてなぜか今回は省略できないので、url が記載されている。

ちなみにこれ url を記述しないとRouting Error になる!

①同様に、form_withが実行された時、渡されたインスタンスの中身が空かそうではないかをRails君が識別する。

今回は新規ユーザー登録なので、paramsが空。

よってRails君の自動識別で空の時の反応がなされて新規登録となる。

しかしユーザー情報の変更や更新の場合、paramsには既にデータが入っているのでupdateアクションへ繋がる、らしい。

 

 

<3><%= form_with(url: search_tweets_path, local: true, method:get, class: "search-form") do |form| %>

 

これは検索窓の記述。

 

ここでは検索フォームに打ち込んだ文字がデータベースに保存される必要はないのでmodelは使われていない。

 

ちなみにまだ勉強不足で、id,class, なぜカッコで閉じる時と閉じない時があるかはまだ調べていない。

 

 

わからないだらけでプログラミング言語は調べ甲斐があるなぁ〜...( ¨)遠い目

というわけで明日も頑張ろう!

Ruby on Rails のdevise gem を使ったユーザー登録機能の実装

今日はRailsのユーザー登録実装について。

少しずつ理解できてきたので復習。

(あくまで私が練習している途中を思い出しているので、手順など異なることもあります。というかなんなら間違ってますのでご容赦ください)

 

新規アプリを実装したとして仮定してgemの導入まですっ飛ばす。

そこからの手順としては

1、devise gemの導入

2、deviseのインストール

3、devise用モデルの作成

4、テーブルの作成

5、新規登録、ログインの画面作成の為、viewsファイルにそのビューファイルを作成

6、(トップページヘッダーにログイン機能をつけるとして)新規登録、ログインのリンクが、ログイン中は代わりにログアウトのリンクが出る様にviews/layoutのapplication.html.erbのyeildメソッドを使っているファイルのヘッダー部にif user_sign_in?構文を使い記述

 

7、新規登録時にデフォルトであるメールやパスワード以外に名前や他のパラメーターも登録する場合はragistrationsディレクトリのnew.html.erbに追加記述

8、コントローラーに記述(ただしdeviseのコントローラーに記述はできないので、共通のapplication_controller.rbに記述)

 

 

6________________________________

<% if user_signed_in? %>

  <%= link_to "新規登録", (Prefix名)_path, method: :get %>

  <%= link_to "ログイン", (Prefix名)_path, method: :get %>

<% else %>

  <%= link_to "ログアウト", (Prefix名)_path, method: :delete %>

<% end %>

___________________________________________________________________________

 

8_________________________________________________________________________

class ~~~

  before_action :configure_permitted_parameters, if: :devise_controller?

 

  private

  def configure_permitted_parameters

    devise_parameter_sanitizer.permit(:sign_up, keys: [:(追加するカラム)])

  end

end

___________________________________________________________________________

 

あってるかな?

 

<自己添削での間違い部分>

・6の新規作成とログインのHTTPメソッド不要だった。

・7ではカラムへのパラメーター追加(マイグレーションファイル編集)も必要

・8の後にはバリデーションが必要

 

他にもありそうだけど…自己採点ではこんなもんかな

理屈より書いて覚えるのがプログラミングの勉強の真骨頂なんだろうな。

 

本当はAWSなども興味あるので勉強して載せようかとも思ったけど、まずは一つの言語に集中した方が良いかと思ったので、今後も基本Railsでいこうと思う。

 

でも、最近思うのは…1日の時間がもっとほしーー!

プログラミングを勉強しているとあっという間に時間が過ぎていく(T . T)

 

とりあえず、週2回、なるべく水、日にブログに何か書いていこうと思う。

さて、次の勉強をしよう。