実装したい事をGoogleで調べるとqiitaの同じような記事が引っかかる現象
参考になることもあるが、「さっき似た記事読んだぞ!」とノイズに感じることもある。どうしたもんか。でも俺がこのブログで書いてるメモも似たようなもんだしなあ。それに「qiitaに初心者がメモ書いちゃいけません」てな決まりもない訳だし。
とりあえず、ネットで調べてもなお引っかかった事をアウトプットしていこうかな。俺もプロ/初心者問わずそういう記事に助けられたので。さあどれからやろうか。
DeepL翻訳とGoogle翻訳の比較
結論
マジ精度高い。けど、グーグル翻訳でも別にそこまで困らない感じ。月額1200円は・・・どうなんでしょ。
翻訳元
minimagickというrails上で画像処理してくれる物の説明書。その一部を引用。
https://github.com/janko/image_processing/blob/master/doc/minimagick.md
原文
#loader
It accepts the following special options:
:loader -- explicitly set the input file type
:page -- specific page(s) that should be loaded
:geometry -- geometry that should be applied when loading
:auto_orient -- whether the image should be automatically oriented after it's loaded (defaults to true)
:define -- creates definitions that coders and decoders use for reading and writing image data
google翻訳
#loader
次の特別なオプションを受け入れます。
:loader-- 入力ファイルの種類を明示的に設定します。
:page-- ロードする必要がある特定のページ
:geometry-- ロード時に適用する必要があるジオメトリ
:auto_orient-- 画像のロード後に画像の向きを自動的に設定するかどうか (デフォルトはtrue)
:define-- コーダーとデコーダーが画像データの読み取りと書き込みに使用する定義を作成します。
deepL翻訳
#ローダー
以下の特殊なオプションを受け付けます:
loader -- 入力ファイルの種類を明示的に設定する。
:page -- 読み込むべきページを指定する。
:geometry -- 読み込み時に適用するジオメトリ。
auto_orient -- 画像を読み込んだ後に自動的に向きを変えるかどうか(デフォルトはtrue)。
:define -- コーダーやデコーダーが画像データの読み書きに使用する定義を作成する。
挫折感(Ajax導入失敗、turbo_frame_tag導入失敗)
概要
駄目だ、心が折れそう。でも頑張る。
何があった
Ajaxは
https://qiita.com/hapiblog2020/items/3ba7e7edc02f01d987b9
turbo_frame_tagは
https://zenn.dev/shita1112/books/cat-hotwire-turbo
を参考に頑張って導入を試みたが、失敗。失敗の痕跡は
https://github.com/blue-night-blue/imgbbs/commits/main
を参照されたい。
今の課題
どの記事もscaffoldを使う(超便利というか基本使うようで。)ことを前提に書いてるので、俺のような愚直にProgateのやり方を通そうとしちゃってる人間からすると、マジで理解が追いつかない。
今後どうするか
根本的にscaffoldでどういう動きをしてるか分かった上でまずscaffoldで作り、そこから導入を目指そうと思う。
悩み
やはり、適性がないのか?こんなところでつまづいてる奴、ネットで検索しても出てこないぞ?とりあえず、俺が諸々でつまづくのは、基礎を分かってないからだと思いたい、というか思い込む他ない。
2023/06/09追記
scaffoldで作り直したらturbo_framesうまく動いてくれました。嬉しいです。が、おせえ。
Progate修了以降に覚えたRailsやRubyのTips
何これ?
俺用のメモ。Progateをやり終えてから学んだrails,ruby絡みのことを今後ここに追記する。新しくrubyのメソッドとかを覚える度にをれを一つの記事にするとネット上のノイズになりそうなので、この記事にまとめることにする。ただ、詳細を記載する必要がある場合は、単独で記事を作る。いいだろ?
ターミナルに書くやつ
パーミッション変更
chmod 数字3桁 ファイル(ディレクトリ)名
テーブルに列追加(migrationに自動で記載される)
rails g migration AddRetsunonamaeToPosts retsunonamae:katanonamae
scaffold
rails g scaffold Post hoge:string hoge:string
herokuの環境変数設定
heroku config:set RAILS_MASTER_KEY=123
herokuの環境変数設定その2
heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
herokuの環境変数を解除
$ heroku config:unset RAILS_MASTER_KEY
rails s停止
ps aux pumaを探す 数字を覚える kill 数字
モデルに書くやつ
activestorage+a3で画像一つだけ投稿
has_one_attached :image
コントローラーかビューに書くやつ
以下、コントローラー、ビューいずれにも書くかもしれないやつ。
0埋め
format("%010d", 123) #0000000123
ファイル削除
2023/05/26時点ではOperation not permitted @ apply2files - public/post_images/ って出るけど。なめとんか、と言いつつ対処法ググり中。なかなか出てこねえ。
2023/06/02追記
これも、そもそもProgateが悪い。binfileの存在しか教えなかったから、投稿された画像をFileでなんとかしようとしちゃうじゃん。だいたい、railsだったらactivestorageとs3を使うのが普通なんだから、それを直接教えて欲しかった。まあ、こういうのを調べるのも含めて勉強なんだろうけど、なんか腑に落ちない。
File.delete("パス")
require,permitメソッド
以下、引用。使ってねえけど。そのうち使う。
もし悪意のある利用者が入力フォームを追加して投稿した場合、受け取るパラメータも変わってしまいます。(中略)Userモデルのname, ageカラムのみを受け取る場合は、以下のように書きます。createメソッド、updateメソッドで共通的に使用するため、user_paramsのように別のメソッドに切り出すのが一般的です。
https://magazine.techacademy.jp/magazine/22078
def user_params params.require(:user).permit(:name, :age) end
whereである数字からある数字まで拾う
@post=Post2.where(post_id:number_from..recent_number)
最後にcreateされた行
Post2.last
画像があったら(activestorage+s3で)
if @post.image.attached?
画像消すし行も消す
@post.image.purge && @post.destroy
前見ていた所にリダイレクト
redirect_to request.referer
タグ列に特定のタグが含まれる行を選択
@post=Post2.where("tag LIKE ?","%#{@tag}%")
小数点のある状態にして小数点以下切り上げ
to_fを使わないと切り上げできなかった。マジで罠過ぎる。というか、俺の勉強不足。railsチュートリアルとかの必要性を感じる。(読みたいが2023/06/02現在、アプリ作りた過ぎて後回し状態。いいのか?)
@pages=(recent_number.to_f/10).ceil
forの書き方
for i in 1..@times
ビューに書くやつ
font awsomeのやつ
Progateで習ったのと違うぞ!2023/06/02現在、ユーザ登録せんと駄目。
<script src="https://kit.fontawesome.com/ユーザ登録したら発行される文字列.js" crossorigin="anonymous"></script>
form_tagの別の書き方
なんか、form_tag自体が推奨されてないみたいだぞ。form_forとこれと併せて、form_withに統合されたとのこと。どうせえっちゅうんじゃ。
<%= form_tag({ :controller => 'home', :action => 'times_post' },{ :method => :post}) do %> <div class="submit_times"> <input class="times" name="times" type="text" value=""> <input class="submit_button_times" type="submit" value="post"> </div> <% end %>
form_with
信じられんぐらい引っかかった。ええ加減にせえ。
<%= form_with url: "/home/create", local: true do |form| %> <p>name<%= form.text_field :name %></p> <p>image<%= form.file_field :image %></p> <p>comment<%= form.text_area :content %></p> <p>tag<%= form.text_field :tag %></p> <p>password<%= form.password_field :password %></p> <%= form.submit "post" %> <% end %>
formでvalue設定
<%= form.text_area :content, :value=>@post.content %>
いい感じで日付表示
<%= post.created_at.strftime('%Y/%m/%d') %>
link_toの別の書き方
<%= link_to("#{tag}",controller: "home", action: "tag", id: tag) %>
activestorage+s3で画像を引っ張る
<%= image_tag post.image %>
改行を反映
<%= simple_format(post.content) %>
link_toとfont awsomeでいいねボタンを作る
data: { turbo_method: :post } でようやく動いた。Progateの嘘つき。Progateだと{method: "post"}って習ったけど動かんかったぞ。あとProgateだとiタグでfaを作れなかった。色々、なんだかなあ感がある。まあProgateも「後はネットで調べてください」てな姿勢ではあるんで、ある程度しゃあないのだろうな。
<%= link_to ({ controller: "home", action: "like", id: post.id}), data: { turbo_method: :post } do %> <i class="fa-sharp fa-solid fa-thumbs-up"></i> <% end %>
配列やハッシュ
カンマ区切りの文字列を配列に変換
to_sが必要っぽい
Foo.find(1).bar.to_s.split(",")
モデルから特定のカラムだけ取り出して配列化する
foos=Foo.pluck(:bar)
配列をカンマ区切りの文字列に変換
上の続き
baz=foos.join(",")
前後の余分な空白を削除
.map(&:strip)
配列から、空を削除
.reject(&:empty?)
配列から、ハッシュに含まれたキーを削除
hash = {"foo" => true, "bar" => true} Buz.reject { |qux| hash[qux] }
重複を削除
.uniq
新しい配列を作成(map先生)
# 各要素を2倍して新しい配列を生成 numbers = [1, 2, 3, 4, 5] doubled_numbers = numbers.map { |num| num * 2 } puts doubled_numbers # 出力: [2, 4, 6, 8, 10] # 文字列の長さを取得して新しい配列を生成 fruits = ["apple", "banana", "cherry", "date"] lengths = fruits.map { |fruit| fruit.length } puts lengths # 出力: [5, 6, 6, 4] # ブロックの戻り値がtrueの要素を選択して新しい配列を生成 numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] even_numbers = numbers.map { |num| num if num.even? }.compact puts even_numbers # 出力: [2, 4, 6, 8, 10] # 配列の中で配列を作る fruits = ["apple", "banana", "cherry", "date"] fruits_true = fruits.map { |fruit| [fruit,true] } puts fruits_true # 出力: [ ["apple",true],["banana",true],["cherry",true],["date",true] ]
ハッシュ化
上の続き
p fruits_true.to_h
# 出力: {"apple"=>true,"banana"=>true,"cherry"=>true,"date"=>true}
マイグレーションファイルに書くやつ(change内)
列リネーム
rename_column :モデル名(全て小文字の複数形), :変更前のカラム名, :変更後のカラム名
ProgateのRailsレッスンのまとめ
説明
ProgateのRailsレッスンで得た知識の要約。このブログやProgateを検索したり、既に学んだことを再度ググるのがめんどくなったのでチートシート的に活用。(ただ、例えばform_tagとかググると、色んなフォームの書き方があることを知ったりできるので、Progateで知ったメソッドとかを再度ググるのは悪いことではないなとは思った。)
ちなみにアプリを使ってもらう前提なので、Progateでは習ってないけどherokuの一連の手順も入れている。
→2023/06/14追記。herokuは別記事にしました。
https://blue-night-blue.hatenablog.com/entry/2023/06/14/163246
ターミナルに書くやつ
モデルに書くやつ
空白は駄目
validates :content, {presence: true}
上記+文字数制限
validates :content, {presence: true,length:{maximum:140}}
重複禁止
validates :email,{uniqueness:true}
インスタンスメソッド(例)
######従来 #posts_controller.rb def show @post = Post.find_by(id: params[:id]) @user = User.find_by(id: @post.user_id) end ######インスタントメソッド使用 #post.rb def user return User.find_by(id: self.user_id) end #posts_controller.rb def show @post = Post.find_by(id: params[:id]) @user = @post.user end
コントローラーに書くやつ
並び替え
@posts = Post.all.order(created_at: :desc) #ascで昇順
戻す(redirect_toと違って、変数をそのまま使える)
render("ビューファイルのあるフォルダ名/ビューファイル名")
フラッシュ
flash[:notice]="メッセージ"
画像を受け取って保存
if params[:image] @user.image_name="#{@user.id}.jpg" image=params[:image] File.binwrite("public/user_images/#{@user.image_name}",image.read) end
find_byで複数条件
@user=User.find_by(email: params[:email],password: params[:password])
session変数
def login @user = User.find_by(email: params[:email], password: params[:password]) if @user session[:user_id]=@user.id #後略
ログアウト
def logout session[:user_id] = nil flash[:notice] = "ログアウトしました" redirect_to("/login") end
ビフォーアクション
before_action :set_current_user
ビフォーアクションを特定のアクションのみに適用
before_action :authenticate_user,{only: [:index, :show, :edit, :update]}
セッションIDがユーザーIDと一致するユーザーをセット
#ApplicationController def set_current_user @current_user = User.find_by(id: session[:user_id]) end #ApplicationController before_action :set_current_user
ログインしているか判定
#ApplicationController def authenticate_user if @current_user == nil flash[:notice] = "ログインが必要です" redirect_to("/login") end end #UsersController before_action :authenticate_user, {only: [:index, :show, :edit, :update]} #PostsController before_action :authenticate_user #LikesController before_action :authenticate_user
ログインしてたらログイン画面から追い出す
#ApplicationController def forbid_login_user if @current_user flash[:notice] = "すでにログインしています" redirect_to("/posts/index") end end #UsersController before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
自分じゃないユーザーページに行ったら追い出す
#UsersController def ensure_correct_user if @current_user.id != params[:id].to_i flash[:notice] = "権限がありません" redirect_to("/posts/index") end end #UsersController before_action :ensure_correct_user, {only: [:edit, :update]}
自分の投稿じゃないやつをいじろうとしたら追い出す
#PostsController def ensure_correct_user @post = Post.find_by(id: params[:id]) if @post.user_id != @current_user.id flash[:notice] = "権限がありません" redirect_to("/posts/index") end end #PostsController before_action :ensure_correct_user, {only: [:edit, :update, :destroy]}
いいね数を表示
@likes_count=Like.where(post_id: @post.id).count
erbに書くやつ
link_to
<%= link_to("表示名","/コントローラー/アクション") %>
eachでモデルからデータを引っ張り出す
<% @配列の変数.each do |任意の変数| %> <div> <%= 任意の変数.配列のカラム名 %> </div> <% end %>
フォーム
<%= form_tag("/コントローラー/アクション") do %> <textarea name="content"></textarea> <input type="submit" value="投稿"> <% end %>
link_toでデータベースをいじる場合
<%= link_to("削除", "/posts/#{@post.id}/destroy", {method: "post"}) %>
errorsメソッド
<% @post.errors.full_messages.each do |message| %> <%= message %> <% end %>
フラッシュ
<%= flash[:notice] %>
フォーム(画像送信)
<%= form_tag("/users/#{@user.id}/update", {multipart: true}) do %> <input name="image" type="file"> <input type="submit" value="保存"> <% end %>
パスワード非表示
<input type="password">
session変数
<% if session[:user_id] %> 現在ログインしているユーザーのid: <%= session[:user_id] %> <% end %>
ログアウト(session変数をいじる際もpostを使う)
<%= link_to("ログアウト", "/logout",{method: "post"}) %>
HTML要素に対してlink_toメソッドを使う
<%= link_to("/likes/#{@post.id}/destroy", {method: "post"}) do %> <span class="fa fa-heart liked-btn"></span> <% end %>
マイグレーションファイルに書くやつ(change内)
追加
add_column :モデル名の複数形(小文字), :カラム名, :データ型 #サンプル add_column :posts, :post_id, :integer #「:posts ,」というようにスペース入ってると通らない!要注意!! #ちなみにPost2というモデルなら「:post2s」になる。俺のようにトチったらこうなる。
削除
remove_column :同上
git
bcrypt関係
- gemに書くやつ:gem "bcrypt"
- ターミナルに書くやつ:bundle insatall
- コントローラー作成時にターミナルに書くやつ:password_digest:string
- モデルに書くやつ:has_secure_password
- ここまでやったら、一旦rails sを切る、そして再度立ち上げ。
- コントローラーに書くやつの一例:if @テーブルから取得した変数.authenticate(params[:password])
Railsで作るにあたってやったこと
いざ実践!ではあったんだけど引っかかりまくったのでメモ。
引っかかったポイント一覧
- ターミナルの概念をよく分かってない(あとで調べる)ので引っかかったのだけど、rails sをする前に「rails g controller home top」とかをしないといけない感じなのね。rails sをした後にそれができないので戸惑った。どういう仕組み?
- ↑なんか、vscodeで複数のターミナルを同時に動かせるっぽいな。一つでrails sして、もうひとつは淡々とrailsコマンドを使う感じなのかな。今の所そうやっている
- ルーターの記載ミスがあった場合、rails sができないのね。そこでも引っかかった。きちんとルーターは書こう。
- erbがvscodeでシンタックスハイライトされないのでキモい→拡張があった https://marketplace.visualstudio.com/items?itemName=wingrunr21.vscode-ruby
- 同じくerbでタグの自動補完ができなくてキモい→拡張があった https://marketplace.visualstudio.com/items?itemName=Cjay.ruby-and-rails-snippets
- 文字を囲んでタグ付けしたい→https://marketplace.visualstudio.com/items?itemName=bradgashler.htmltagwrap
- githubにアップ(というかpushっていうのね)するのは簡単だったんだけど、実際に動いてるところを見たいなあと思って色々調べていると、herokuがいいそうで。めっちゃ苦労して導入しましたがな・・・。
- とにかくherokuに反映されないし、原因追求のためターミナルでherokuコマンド使ったらそもそも使えないしで、調べに調べに調べた結果、https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39 の記事の通りにやったらすべてうまく行った!感謝しかない!
作ったもの
簡易なbbs(掲示板)です。2000年代初頭の香り・・・。もうちょい手を加えますが。
どうでもいいけど
ギフハブを思い出した
Rails環境構築
手順
- rbenv versions でRubyのバージョン確認 ※Rails 7系はRuby 2.7以上が必要
- gem install rails -v 7.0.3 でインストール
- rails -v でバージョン確認。ダメなら https://k-koh.hatenablog.com/entry/2020/01/21/120142 を参照(今回はターミナルに export PATH="$HOME/.rbenv/shims:$PATH" と打ったら行けた)
- rails new hoge で作りたいものを作る
- cdとlsで、hogeがきちんとできているか確認
- cdでプロジェクトのフォルダに移動しておく。そうしないと↓のサーバー起動できない
- rails s でサーバー起動 ※control + c でサーバー止める
- ブラウザに localhost:3000 を入力