BNBのプログラミング勉強記録

ガチのプログラミング初心者が駆け上がっていくブログ

実装したい事を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のメソッドとかを覚える度にをれを一つの記事にするとネット上のノイズになりそうなので、この記事にまとめることにする。ただ、詳細を記載する必要がある場合は、単独で記事を作る。いいだろ?

ターミナルに書くやつ

パーミッション設定の確認

これと↓のやつは、そもそも、投稿画像をFileでなんとかしようとしていた際に調べていたこと。Progateが悪い(多分違う)。

ls -al

パーミッション変更

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("#{tag}",controller: "home", action: "tag", id: tag) %> 

activestorage+s3で画像を引っ張る

<%= image_tag post.image %>

改行を反映

<%= simple_format(post.content) %>

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

ターミナルに書くやつ

  • アプリを作る:rails new アプリ名
  • コントローラーを作る:rails g controller コントローラー名 アクション名
  • モデル(テーブル)を作る:rails g model モデル名(最初大文字で単数形) カラム名:データ型 カラム名:データ型 ※データ型の例:string,text,integer
  • モデルに変更を加える:rails g migration カラムを追加するよ的な名前

モデルに書くやつ

空白は駄目

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("表示名","/コントローラー/アクション") %>

eachでモデルからデータを引っ張り出す

<% @配列の変数.each do |任意の変数| %>
      <div>
          <%= 任意の変数.配列のカラム名 %>
      </div>
<% end %>

フォーム

<%= form_tag("/コントローラー/アクション") do %>
      <textarea name="content"></textarea>
      <input type="submit" value="投稿">
<% end %>
<%= 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"})  %>
<%= 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

  1. githubへ行き新規のリポジトリを作る
  2. 上記のリポジトリURLをコピーしとく
  3. cdでアプリのディレクトリへ行く(違うところにおらんように。add出来んくなるぞ!)
  4. git init
  5. git remote add origin リポジトリURL
  6. git add .
  7. git commit -m "メッセージ"
  8. git push origin main

bcrypt関係

  • gemに書くやつ:gem "bcrypt"
  • ターミナルに書くやつ:bundle insatall
  • コントローラー作成時にターミナルに書くやつ:password_digest:string
  • モデルに書くやつ:has_secure_password
  • ここまでやったら、一旦rails sを切る、そして再度立ち上げ。
  • コントローラーに書くやつの一例:if @テーブルから取得した変数.authenticate(params[:password])

Railsで作るにあたってやったこと

いざ実践!ではあったんだけど引っかかりまくったのでメモ。

引っかかったポイント一覧

作ったもの

簡易なbbs(掲示板)です。2000年代初頭の香り・・・。もうちょい手を加えますが。

どうでもいいけど

ギフハブを思い出した

Rails環境構築

手順

  1. rbenv versions でRubyのバージョン確認 ※Rails 7系はRuby 2.7以上が必要
  2. gem install rails -v 7.0.3 でインストール
  3. rails -v でバージョン確認。ダメなら https://k-koh.hatenablog.com/entry/2020/01/21/120142 を参照(今回はターミナルに export PATH="$HOME/.rbenv/shims:$PATH" と打ったら行けた)
  4. rails new hoge で作りたいものを作る
  5. cdとlsで、hogeがきちんとできているか確認
  6. cdでプロジェクトのフォルダに移動しておく。そうしないと↓のサーバー起動できない
  7. rails s でサーバー起動 ※control + c でサーバー止める
  8. ブラウザに localhost:3000 を入力