seedデータの変更は削除する必要がある!
ハマったエラーについて書いていきます
- エラー時の状況
・CRUD処理実装と'devise' gemでログイン処理を実装後に、localhost:3000で入ると
というエラーが出る
この時の主なコードはこちら
- ルート
Rails.application.routes.draw do
root to: 'posts#index'
devise_for :users
resources :posts
resources :users, only: :show
end
- コントローラ
Postsコントローラ
class PostsController < Application Controller
before_action :move_to_index, except: :index
def index
@posts = Post.all
end
def new
@post = Post.new
end
def create
Post.create(content: post_params[:content], user_id: current_user.id)
end
def move_to_index
redirect_to action: :index unless user_signed_in?
end
private
def post_params
params.require(:post).permit(:content)
end
end
Usersコントローラ
class UsersController < ApplicationController
def show
@user = User.find(current_user.id)
end
end
- モデル
post.rb
class Post < ApplicationRecord
belongs_to :user
end
user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :postsend
- ビュー
views/posts/index.html.erb
<h1>投稿一覧</h1>
<% if user_signed_in? %>
<% @posts.each do |post| %>
<p><%= post.content %>:会員No.<%= post.user.id%></p>
<% end %>
<% else %>
<p>ログインしてください</p>
<% end %>
- データベース(sqlite3)
postsテーブル
class CreatePosts < ActiveRecord::Migration[5.2]
def change
create_table :posts do |t|
t.text :content
t.integer :user_id
t.timestamps
end
end
end
- seed
Post.create(content: "熱rjrhje狂のWebマrhjerjhjーケティンsprnhグ", user_id: 1)
Post.create(content: "g熱rjrhjhグ", user_id: 2)
Post.create(content: "ehrehンsprnhグ", user_id: 3)
Post.create(content: "gnrnbn熱rjrhje狂のW", user_id: 4)
以上です
結果から言うと、問題があったのはseedの部分とデータベースです(コントローラやビュー等には問題無し)
エラーの原因はデータベーステーブルに登録されているカラムは:contentと:user_idなんですが、postモデルを作成した時に:user_idカラムを入れ忘れて後からadd_column で追加したんですけど、その間にseeds.rbで上記のデータを入れた為に:contentのみで:user_idが無いデータを作成した事になっていて、追加後にもう一度
bundle exec rake db:seed
で入れ直した時に前のデータは消えて新しいデータのみになると思ったところ、古いデータに新しいデータが追加され存在しカラム無しの古いデータが読み込めないからNo Method Error NilClassが出たようです。
今回の解決方法は既存のseedデータを修正した場合、前のデータがエラーの原因になっていて消す必要があるためRails Controllerで
Post.delete_all
でデータを削除後に
bundle exec rake db:seed
でデータを入れ直すことで正しいデータのみが残りエラーが解決しました!
追記
seedデータによく変更を加える場合は
rails db:migrate:reset db:seed
でデータベースの削除&作成を一度で出来るそうです!
Git アップロード 仕方
Githubでアップロードの仕方を覚えたので、忘れないように書いていきます
リポジトリやブランチの概念を理解するのにかなり時間がかかりました…
前提条件としてGithubのアカウントを持っている事と、(これは後ででもいいけど)repositoryをアカウントから作成しておくことです
以下の操作は全てターミナルで行います
まずにgitにアップロードしたい好きなフォルダに
cd フォルダ名
で移動して
git init
でgitにアップするフォルダorファイルを指定します
そして
git add .
or
git ファイル名
でアップロードする準備みたいなものをします
git commit -m "変更についてのメッセージ"
で変更の保存と何を変更したか分かりやすいようにメッセージを書きます
次に
git branch ブランチ名
でブランチを作ります
ブランチというのは保存先みたいなものです
さらにブランチが作れたら
git branch
や
git checkout ブランチ名
で移動出来ます
追記(9/17)
git checkout -b ブランチ名
の作成と移動が同時に出来ます!
そして
でリモートリポジトリを作成します
リモートリポジトリは保存先の保存先みたいな感じ
gitのrepositoryのurlはrepositoryの中の緑色の"clone or download"をクリックするとリンクが出てくるのでそれをコピー
そしてついに
git push リポジトリ名 ブランチ名
でアップロード完了です!
正直これだけでも理解するのに1時間半くらいかかりました笑
しかも"こうなるとこういう風になるんだなぁ"と言うような漠然とした概念を掴んだだけでまだ理解は出来てない…
これから使う内に理解出来るようにします
今日は以上でーす💤
Rails ログイン/ログアウト/アクセス制限機能について
今回の記事では
- ログイン機能
- ログアウト機能
- ユーザー名の表示
- アクセス制限機能
について書いていきます
- ログイン機能
ログイン機能は長くなるので工程を書いておきます
- get "login"とpost "login"ルーティングの作成
↓
- users/login_form.html.erbビューを作成
↓
- パスワードカラムを追加
↓
- フォームの送信に関して書く
↓
- usersコントローラに中身を書いていく
まずルーティングから
get "login" => "users#login_form
post "login" => "users#login"
先頭に付いているgetとpostが違うのあれば名前が一緒でもいいそうです。
次にusersフォルダにlogin_form.html.erbファイルを作成します
そこにユーザー情報を送信出来るようにinputなどを書いていくのですがその前にpasswordを追加したいので前回やったようにusersテーブルにpasswordカラムを追加します
ターミナルで↓を書き
rails g migration add_password_to_users
db/migrateフォルダ内の"更新データの日付_add_password_to_users.rb"ファイル内に↓と書きます
def change
add_column :users, :password, :string
end
これでパスワードカラムがDBに追加されました
rails db:migrate
を忘れずに!
次はフォームの送信が出来るようにlogin_form.html.erbファイルにメールアドレスや名前等(ここでは省略)に加えてパスワードを追加します
<%= form_tag("/login") do %>
〜各種送信するフォームの中身(email,name等)〜
<p> パスワード</p>
<input type="password" name="password" value="<%= @password %>">
<% end %>
type="password"は入力した文字が黒塗りで見られないようにするもので、value="<%= @password %>"は初期値を表示するためです
@passwordは後でコントローラ内で定義します
次はusersコントローラに"login_form"と"login"を定義して、"login"の中身を書いていきます
def login
@user = User.find_by("email: params[:email], password: params[:password]")
if @user
session[:user_id] = @user.id
flash[:notice] = "ログインしました"
redirect_to("/posts/index")
else
@error_message = "〜"
@email = params[:email]
@password = params[:password]
render("users/login_form")
end
end
まずフォームから送信された情報をfind_by("〜")で取得します
次に情報が取得出来た後、@userが存在する場合、
session[:キー名]というのはこれに代入した情報を送信し続ける変数です(ここではユーザーの情報を送信することでページを移動しても情報が保持されログイン状態が続くという仕組み)
else以降は@error_messageでエラーメッセージを表示し、@email = params[:…]と@password = params[:…]はビュー内のvalue="〜"で初期値を表示するためのものです
- ログアウト機能
まずはルーティング
post "logout" => "users#logout"
sessionの値を変更する場合もDBの変更の時と同じようにpostを使います
ではコントローラを書いていきます
def logout
session[:user_id] = nil
flash[:notice] = "〜"
redirect_to("/login")
end
session[] = nilにすることで送信する情報を空にすることが出来ます(ターミナルでのrails server起動時にctrl+Cを押して接続をキャンセルするみたいな感じ?)
後はログアウトリンクに忘れずに{method: "post"}を指定してくださいね
- ユーザー名の表示
applicationコントローラ内で定義したアクションをbefore_actionで他のコントローラやビューでも使えるというものなのですが、
このbefore_actionを使ってユーザー名の表示をしていきます
まずapplicationコントローラ内に
before_action :set_current_user
〜省略〜
def set_current_user
@current_user = User.find_by(id: session[:user_id])
end
を定義します
これは@current_userでログイン中のユーザーidを取得しているという意味です
そしてbefore_action :〜で他のアクションでも使えるようにします
そしてlayout/application.html.erbファイル内のヘッダーリンク部分に
<il>
<%= link_to(@current_user.name, "/users/#{@current_user.id}") %>
</li>
と書けばログイン中のユーザー名が表示されます
- アクセス制限
これも基本的には
applicationコントローラ内で定義したアクションを各コントローラ内でbefore_actionを使うものになります。
例えばログインしていないユーザーがログインしているページに入ろうとした場合に
def authenticate_user
if @current_user == nil
redirect_to("/login")
end
end
と定義しておけば、これをログインして欲しく無いページのアクションに指定しておけば、このアクションが発動されてアクセスが制限されるというわけです
例:usersコントローラ内のedit,updateアクションでこのアクション(authenticate_user)を行いたい場合、usersコントローラ内で
before_action :authenticate_user, {only: [:edit, :update]}
と適用したい任意のアクションをonlyで指定します
後はログイン中のユーザーが別のユーザーの編集を出来ないように、(ここではusersコントローラ内でのみ適用させるので)usersコントローラ内で
before_action :ensure_correct_user,
{only: [:edit, :update]}
〜省略〜
def ensure_correct_user
if @current_user.id != params[:id].to_i
redirect_to("/posts/index")
end
end
を定義します
ポイントは@current_userが params[:id]で受け取った値と比較する場合に params[:~]は文字列でしか受け取れないので.to_iを使って数値に変換する必要があるところです
今日はこれで以上です。
初めて3000文字以上書きましたが時間がかかり疲れました…
いつも1000文字当たり1時間くらいかかるので(今回は2.5時間くらい)なかなか更新するのは大変ですが、良いアウトプットだと思い頑張って続けます💪
いつも読んでくださりありがとうございます🙏
Rails 画像のアップロード機能
今回の記事では
- 画像のアップロード機能
について書きます
画像のアップロードにはまず画像のデータをデータベースに保存するためのカラム(ここではuser_image)を追加します
*ターミナルへの記述は青で書きます
rails g migration add_image_name_to_users
注意するのはmigrateでは無くmigrationと記述することです
これでdb/migrate/にファイルが作成されるのでそこで
〜省略
def change
add_column :users(テーブル名), :image_name(カラム名), :string(データ型)
end
省略〜
これらはターミナルからではなく、ファイルからdbの変更を加える操作です
しかし変更の方はターミナルで操作しなければなりません
rails db:migrate
次はユーザー登録画面で登録時点でのデフォルトの画像をusersコントローラのcreateアクションに追加します
def create
@user = User.new(
name: params[:name]
email: params[:email]
image_name: "指定の画像のURL"
)
省略〜
end
次はビューに画像を表示させます画像を表示させたい.html.erbファイル内に
<img src="<%= "/画像の入っているフォルダ名/#{@user.image_name}" %>">
次は画像を送信出来るようにusers/edit.html.erbファイル内に
<%=form_tag("...", {multipart: true}) do %>
と
<input name="image" type="file">
を追加します
最後にusersコントローラ内のupdateアクションに
def update
〜省略
@user.image_name = params[:image_name]
if params[:image]
@user.image_name =
"#{@user.id}.jpg"
image = params[:image]
File.binwrite("public/フォルダ名/#{@user.image_name}", image.read)
end
省略〜
end
と書きます
@user.image_name = params[:image_name]
は画像のファイル名をimage_nameカラムに保存する為のものです
if params[:image]
@user.image_name =
"#{@user.id}.jpg"
image = params[:image]
は画像データが送信されたらimage_nameカラムに画像のファイル名を代入し、
imageで送信されたものを受信し、
File.binwrite("〜")
は画像データをファイル内に作成するもので、()内の.readメソッドはその画像データを読み込むためのものです
今回は以上です。
最後の方に新しい知識がたくさん入ってきたので少し難しいですね。
Rails 投稿の編集&削除機能の追加
今回の記事では
- 編集機能の追加
- 削除機能の追加
を説明します。
まず編集機能ですが、これは仕組み自体は新規投稿と一緒で、違うのは新しく作り出して保存する事と値を取得して保存する事です。
削除も編集機能の値の処理が少し違うだけなのでここでは一緒に記述していきます
まずルーティング
〜省略
get "posts/index" => "posts#index"
get "posts/new" => "posts#new"
get "posts/:id" => "posts#show"
post "posts/create" => "posts#create"
get "posts/:id/edit" => "posts#edit"
post "posts/:id/update" => "posts#update"
post "posts/:id/destroy => "posts#destroy"
〜省略
新しく記述したものは太字です
:idは複数の物からそれぞれの固有のデータを取得する必要があるものルーティングの中に入っています
次にコントローラ内に空でいいのでそれぞれのアクションを追加します
そしてまずshow.html.erbファイル内に
編集・削除のリンク項目を追加します
<%= link_to("編集", "/posts/#{@post.id}/edit") %>
<%= link_to("削除", "/posts/#{@post.id}/destroy", {method: "post"}) %>
この{method: "post"}というのは直接link_toでルーティングにpostを持つアクションに飛ばしたい時に指定します(postはgetと違って.html.erbのファイルを作らないから)
次にedit.html.erbファイルを作成します
ファイル内には
〜省略
<%= form_tag("/posts/#{@post.id}/update") do %>
<div>
< textarea name="content">
<%= @post.content %>
</textarea>
<input type="submit" value="保存">
</div>
<% end %>
form_tagは新規投稿と同じでupdateアクションへ送信するためで、そのために textarea内のnameにcontentを指定しています
<%= @post.content %>は初期値として入力される内容です
最後にコントローラ
〜省略
def edit
@post = Post.find_by(id: params[:id])
end
普通に値を取得しているだけです
投稿に失敗した際の初期表示のための定義ですね
def update
@post = Post.find_by(id: params[:id])
@post.content = params[:content]
@post.save
redirect_to("/posts/index")
end
まず値を取得し、textareaのnameで指定されているcontentを取得した後に保存して投稿一覧に遷移しているという意味です
def destroy
@post = Post.find_by(id: params[:id])
@post.destroy
redirect_to("/posts/index")
end
値を取得し、削除、一覧へ遷移、簡単ですね、削除機能で気をつけるのはlink_toでのメソッドを"post"に指定するのを忘れない事です
今回はかなり雑になりましたがこれで終わります。
かなり頭で整理出来てきました。
高校中退からフリーランスを目指すようになるまで
今回もブログのタイトルである高校中退からフリーランスエンジニアを目指すようになったきっかけと経歴の全2回の後編を書いていきます。
- なぜ高校を中退したのか
- フリーランスエンジニアを目指すまで
僕は高卒認定を取得し丁度2年生の終わりで高校を中退しました。
そして1年間は予備校の自習室に通い、勉強をし続ける実質浪人生のような生活になりました。
しかし…最初の1ヶ月は毎日8~10時間くらい勉強し、成績も良く伸びたのですが
次の月には一気に勉強時間が減り、夏が始まるころには1日3時間程度しかしなくなりました…
そして秋を迎えるころには勉強しない日すらあるようになり、学力は伸びないどころか落ち始めていました。
12月の願書を出す頃には"これは落ちるな"と確信をしていた(諦めきっていた)程です。
1月とかは1ヶ月まるごと勉強しなかった気がします
2月、3月くらいに少しくらい落ちた学力を取り戻そうとして最後の足掻きで少し勉強を再開しましたが、沼に頭のてっぺんまで浸かっていたので何の意味も無いまま受けて落ちました
"落ちたら死んでやる"というくらいの覚悟をもって高1の時に受験を始め、現役合格を目指していたので受験前に落ちるのがわかっていても、とてもショックでしばらくは何もする気が起きませんでした…
その後一度は再受験をしようと浪人生として勉強を再開しましたが、実質1年間宅浪をしていて成績が伸びなかったどころか後半には成績が落ちたのを思い出し、踏ん張れる程の情熱や忍耐力も既に無く、結局2週間くらいで浪人生活は終了し、心が完全に折れました。
そこから1年くらいは何をやっていたのかあまり覚えてませんが、1日中ボーッとしていたと思います。
僕はこの時、死ぬ運命が来るまでは自分はもう一生惨めな思いをしながら生きていくしか無いのだなと思い、日々を無為に過ごしていました…
学習性無気力感ってやつですね
そんな中でも実家の恵まれた環境の中では1日が過ぎるのは暇で、なんとか暇を潰せないかと色んな趣味を見つけてはすぐに飽きて、取っ替え引っ替え新しいのを見つけやっていました。
お絵かき、音楽鑑賞、チェス、将棋、ゲーム、読書、映画などです(ここにあげた趣味はほとんどお金のかからないものばかり)
この時自分はとても怠惰な人間で何一つ続かず、続かないということはこの世で最も価値が低いことと考えていました。
しかし月々変わる趣味の中でも唯一続いていたのが音楽鑑賞で、その内に自分も音楽を作りたいと思うようになり、アルバイトをして貯めた10万円を中古の自作PCと周辺機器+作曲ソフトに費やし作曲を始めました。
すると昔は音感が無いと何も出来ないと思っていたのですが、色々なことを調べる内に音楽理論による体系的な作曲方法を知ることになり、音感が無くても作品の質を問わなければ作曲が出来るようになりました。
そして作曲自体は毎日楽しんでやる事が出来、とても充実した日々でした。
この時中学校の時に美術で作品を作ることで味わった充実感を思い出し、続ける事を目的とせずに"純粋にそれ自体を楽しめる事は続くんだ"と感じ、同時に物を生み出すという事に至上の達成感・喜びを感じました
しかしそんな日々も長くは続かず、今度は将来の不安が頭の中で日々大きくなり、"何とかしてお金を稼がないと"という焦りの中純粋に楽しめなくなってしまいました。
しかし普通に就職するのではいくら好きな趣味があっても、ショボい人生を送るのは完全に目に見えていたので"それは絶対に嫌だ"と思い、探し当てたのがプログラミング業界です。
以前はプログラミングはすごく専門的な職業のイメージであまり興味が無かったのですが、プログラミングの世界では高収入、人材不足、学歴不問、先進的技術、そしてクリエイティブなどのキーワードが飛び交っていてとても興味が惹きつけられました。
そして調べた結果
- リモートワークOK→空間的制約に囚われない
- (営業等とは違って)必ず制作物がある→作品として結果を残す事が出来る
などの理由から"これは自分にピッタリだ"と思いフリーランスエンジニアを目指す事に決めました!
(以上を思ったのが2ヶ月前くらいです)
長くなりましたが、ここまで読んでいただきありがとうございました😊
なぜ高校を中退したのか
こんにちは😃
ブログのタイトルである高校中退からフリーランスエンジニアを目指すようになったきっかけと経歴を2回に分けて書いていきます。
- なぜ高校を中退したのか
- フリーランスエンジニアを目指すまで
それでは
今日は
なぜ高校を中退したのかについて…
まずこの話をするには高校入学時から話さなければなりません。
僕は高校受験で第1志望の公立高校に滑り、滑り止めの私立高校に入学しました。
しかし、高校の入学式の時に学校のレベルが低すぎてとてもビックリしたのをよく覚えています。(自分が入った選択コースは1番アホなコースだった)
入学式では校長を含む何人かの先生方達が話されてたのですが、その中でも学年主任の方が
高校はもう義務教育じゃないからね、学校の規則が守れないなら辞めてもらう
みたいな事を話していてとんでもないところに来てしまったなぁと思いました(学校自体は特進コースもある地方の自称進学校レベルです)
高校入学した最初の1週間は人生の目的もまるで無かったし、音楽でも適当にやろうかなーと思ってたけど、音感とかが全然身に付かない事にムカついてきてすぐに辞めました。
そして無期限の暫定感の中で
"ここから人生を変えるには大学受験しかない!"と一念発起して高校入学後1週間で大学受験を決意し、情報集めから始めました。
この時が人生で初めての独学になります
そしてすぐに中学校の復習から開始し、1ヶ月後には予備校に入り授業は殆ど取らずに参考書中心の学者プランを立て自習室で毎日勉強する日々が続きます。
しかしその中でも受験科目外の授業に時間を取られることや自分の参考書を進めてると教師に妨害されるなどの出来事が重なり、早く高校を辞めたいなぁと思いが募る反面、大学受験には高校卒業資格が必要というジレンマに悩まされます。
そう思って学校を早く辞める方法を調べている時に高卒認定試験の存在を知ります。
(高卒認定試験とは高校へ通ってない人、もしくは何らかの理由で高校を中退した人を対象とした大学受験資格を得ることが出来る試験です。)
※高卒認定試験合格では大学受験資格を得るだけであって高校卒業とはみなされない
この存在を知った僕はすぐに高卒認定を取得するために動き始め、さらに高校の在籍年数によって試験科目が免除されるとの事だったので高校2年まで在籍することを決め3年になる前に中退しました。
〜続く〜