うめぼしジョイスティック - ivoice

CakePHP、JavaScript、jQuery等のプログラミングについて書いていきます 思考は、うめぼしのように硬く、そして柔らかく。

Railsのあれこれ その2

メールアドレスのバリデーション(重複なし)

メールアドレスは被らないようにするため、バリデーションを使います。

validates :email, {presence: true, uniqueness: true}

Userモデルでこのようにバリデーションを定義します。

また、ユーザー名は

validates :name, { presence: true }

このような感じで良いでしょう。


Herokuの残り時間

Herokuの無料プランの残り時間を確かめるためには

コマンドライン

heroku ps 

と打ちましょう。

Free dyno hours quota remaining this month: 660h 40m (66%)

という感じで残りの時間とパーセントが表示されます。


Showアクション(詳細ページ)

詳細ページは

まずルーティングを作ります。

showのルーティングは

  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"

このような順番になることに注意して下さい。 (get "posts/index" => "posts#index"よりも下に書く)

次にアクションを記述します。

def show
@post = Post.find_by( id: params[:id])
end

のようにしてコントローラーにshowアクションを作ります。

ビューには

show.html.erb というファイルに

  <div class="container">
    <h2><%= @post.content %></h2>
    <p><%= @post.updated_at %></p>
  </div>

例えばこのようにして、表示させたいテーブルを表示させるようにすればOKです。

また、indexページ(一覧ページ)にリンクで

<% @posts.each do |post| %>
<%= link_to( post.content , "/posts/#{post.id}" ) %>
<% end %>

このように、showページ(個別ページ)に飛ぶようにリンクを設定します。

コントローラーは

コマンドライン

rails g controller users index

などと書いて 「users」「posts」コントローラーのように複数形でコントローラーを作り、 (PostsController、UsersControllerなど)

モデルを呼ぶ時は

  def show
    @user = User.find_by(id: params[:id])
  end

このように単数形で呼ぶことに注意しましょう。


Railsのあれこれ その1

エラーメッセージ

コントローラー

@post.errors.full_messages

でエラーメッセージを取得する。 この場合は

@post

というインスタンスに入ったエラーメッセージをすべて取得している。

これをビューで表示させるには

<% @post.errors.full_messages.each do |message| %>

 <%= message %>

<% end %>

とすればよい。 eachでループを回してすべてを表示させる。


フラッシュ

フラッシュのメッセージを表示させる。

コントローラーで

flash[:notice] = "入れたいメッセージ"

と書くと、フラッシュのメッセージが1回だけ表示できるようになる。

実際にビューで表示させるには

app>>views>>layouts>>application.html.erb

の中で

<header>
</header>

#ここを追加
    <% if flash[:notice] %>
      <div class="flash">
        <%= flash[:notice] %>
      </div>
    <% end %>
#ここまで追加

    <%= yield %>

とすればよい。


renderメソッドについて

renderメソッド。 別のアクションを経由せずに、直接ビューを表示するためのもの。

render("フォルダ名/ファイル名")

とすればよい。

投稿に失敗したときにもう一度投稿画面を表示するときなどに使う。

アクション内で定義していた@変数は、ビューで使うことが可能。

ルーティング(routes.rb)で

get "posts/:id/edit" => "posts#edit"

などのようにしていた場合でも

renderメソッドでは

render("posts/edit")

などのようにすればよく、id番号は必要ない。


記事の投稿

投稿をするばあいは get ではなく post を使う。

ルーティング(routes.rb)に

post "posts/create" => "posts#create"

を追加。 コントローラーにcreateアクションを追加する。

createアクションの中身は

  def create
    @post = Post.new(content: params[:text])
    if @post.save
      flash[:notice] = "投稿を作成しました"
      redirect_to("/posts/index")
    else
      render("posts/new")
    end
  end

のようにして、投稿に成功するとフラッシュメッセージを出すようにし、 投稿に失敗した場合はもう一度、newアクションに行くようにする。

newアクションは

  def new
    @post = Post.new
  end

とすればよい。

ビューは、createは必要ない。 new.html.erbというビューのファイルを作り、

     <%= form_tag("/posts/create") do %>
        <% @post.errors.full_messages.each do | message | %>
        <%= message %>
        <% end %>
        <textarea name="text"><%= @post.text %></textarea>
        <input type="submit" value="投稿">
    <% end %>

このようにすればよい。 エラーメッセージを表示させているのと、

 <textarea name="text"><%= @post.text %></textarea>

のようにして、textareaタグの中で、投稿が失敗した場合に投稿前のテキストが入るようにしてあるのがポイントである。


削除について

投稿の削除は

ルーティング(routes.rb)で

post "posts/:id/destroy" => "posts#destroy"

のようにする。

postであることに注意する。(destroyとupdate、createはpostである。createにはidは要らない。)

アクションは

  def destroy
    @post = Post.find_by(id: params[:id])
    @post.destroy
    flash[:notice] = "投稿を削除したよ"
    redirect_to("/posts/index")
  end

のようにすればよい。

リンクは

<%= link_to("削除", "/posts/#{@post.id}/destroy", {method: "post"}) %>

のようにリンクを貼る。

destroyのリンクでは

{method: "post"}

のようにして「postである」ということを明示する。 投稿フォームではないので、このような記述が必要になる。


Railsで投稿にバリデーションを設定する

Railsで投稿にバリデーションを設定する場合には、バリデーションを設定したいモデルで宣言をします。

class Post < ApplicationRecord

  validates :text, {presence: true, length: {maximum: 100}}

end

Postというモデルでtextという名前のテーブルに、「入力なしは禁止、最大で100文字」のようにするときは上記のようになります。

  validates :text

でバリデーションを宣言して、そのあとはカンマのあとのカッコ 

{ }

の中に条件を書いていきます。

presence: true

は、英語そのまま「存在する」ということが真である、という意味。

length: {maximum: 100}

は、長さ指定で「最大100文字まで」ということですね。

条件はカンマで次々に書いていきます。

HerokuにRails5を独自ドメインでSSLでデプロイする方法(自分にしか分からないレベルのメモ)

HerokuにRails5をSSLでデプロイする方法です。

・アプリケーションはHerokuにデプロイ済みであること。

ドメイン名は仮に sample.com とします。

・CloudFlareを使います。

アプリ名は hello-appとします。

まず、CloudFlareで設定をします。

【完全無料】Herokuで独自ドメイン + HTTPSに対応する【Rails】 - Qiita

まぁぶっちゃけこれをそのまま行うだけです。上記のURLに書いてあることをすべて行って下さい。

ただ、CloudFlare上の設定で、SSLの設定を「Full」にしたつもりでも「Flexible」になっているので、確認してみて下さい。「Flexible」になっていたら「Full」に変えるだけです。

お名前.comなどでドメインがお名前.comのネームサーバーの設定になっている場合は、 ネームサーバーの設定(お名前.comのほう)でCloudFlareのネームサーバーに変えて下さい。(これも上のURLに書いてありますね)

また、Railsの config/environments/production.rb というファイルの

config.force_ssl = true (コメントアウトになっているもの) の、コメントアウトを外すのもポイントです。(これも上のURLに書いてありますね)

さて、このままだと、ドメインにアクセスしても「There's nothing here, yet.」と表示されるだけで、herokuには繋がるものの、アプリケーションが動きません。

そこで、Railsのプロジェクトに移動し、

ローカル環境のターミナルから

heroku login して、

heroku domains:add www.sample.com(ドメイン名) と打ちます。

wwwがついているのがポイントです。 (herokuは2018年現在ではwwwなしのルートドメインは設定できません。 色々やると今も出来るようですが今回は説明しません訂正。無料プランではwwwなしは無理でした。

そうすると 「heroku domains:wait 'www.sample.com'」をRUNしろ、とメッセージが出るので、

heroku domains:wait 'www.sample.com'

とターミナルに打ちます。

以上でRails5で、SSLで無料でherokuでデプロイが完了です。

最初のURLに書いてあった方法で大丈夫なのですが、自分が忘れない用にメモでした。(あと、万が一上のブログが消えると困るので)

そういえば、一番始めはConoHaのVPS(Cent OS)でデプロイをしていたのですが、ConoHaだとアプリを変更した場合に、いちいちログインしてRailsを止めて、pullしないといけないのかな?という運用面での疑問が出てきたのでHerokuにしてみました。 (この部分は本当に分かっていないです。)

全部無料で最初は運用できるという点も大きいです。 (Heroku無料プランは30分アクセスしないとSleepしてしまいますが)

しばらくこれで色々やってみて、慣れてきたらHeroku有料プランにするか、ConoHaでもやってみようと思います。

RailsをGitで管理するための最初の設定(自分用メモ)

RailsをGitで管理するための最初の設定のようなもの。自分メモ。うろ覚えです。 とりあえず分かれば良い的な感じ。

Gitで最初にRailsを管理するための下準備的なもの。

あらすじ

[Linux上で]

hello_appというフォルダでRailsアプリ作成。(rails new hello_app)

[Webで] Bitbucketで hello_app という名前のリモートリポジトリを作成。

そうしたらBitbucketが「README.mdファイルを作りませんか?(ドヤ」と聞いて来たので何となく作ってしまう。(悲劇の始まり) これでリモートリポジトリにREADME.mdファイルがmasterにある状態になってしまった。

まとめると

・Bitbucketのリモートリポジトリ hello_app のマスターに README.md ファイルが1つ上がっている。(Bitbucketでリモートリポジトリを作成した時に作ったもの。)

Linuxローカルhello_appフォルダにはhello_appという名前のRailsアプリがある。そしてその中にはRailsの生成した README.md ファイルがある。(上記とは違うもの)

こんな変な状態。 これではReadmeファイルが競合してうまくいかない。

それの解決方法。

昨日の記憶なので間違っているかもしれません。

解決方法

まず、リモートリポジトリをgit cloneかgit pullして(どっちか忘れた。git cloneしてからgit pullしたかも) LinuxのローカルフォルダをReadmeファイルだけにする。(Railsは消える。)

Railsアプリが消えてしまったので、hello_app内で rails new hello_appをする。

しかし、その方法だと、「hello_appフォルダ内にhello_appフォルダが出来てしまう」ので(当たり前)、間違いだった。rmコマンドで消す。

hello_appフォルダの1つ前の階層に戻り、そこで rails new hello_app をする。

そうすると、「既にreadmeがありますがどうしますか?」と聞かれるので、書き換えるか残すかどちらか選ぶ。(残すを選んだ)

hello_app内に戻り、lsでRailsのファイルが出来ているか確認。出来ている。

git remote add origin url【~/リポジトリ名.git。Bitbucketのリモートリポジトリから取得】

で、リポジトリをoriginという名前で登録する。 これは何をしているかというと、gitのURL(リモートリポジトリ)にニックネームを付けている感じ。(この場合 originという名前。名前はなんでも良い)

git config -l でリポジトリの確認。

ついでに言うと git remote rm origin でoriginを削除

そうしたら、今ある内容を共有リポジトリにプッシュする。

まず git add . で、今あるすべてのファイルをステージングエリアに追加。

git commit -m "コメント" でコメントを追加。

git push origin master   「originに向かって、masterの内容を突っ込んで下さい」という意味になる。

これで完了。

参考: ドットインストールのGit入門(全22回) https://dotinstall.com/lessons/basic_git

その他:

「Git超入門:"git push origin master"の"push"と"origin"と"master"の意味がわからないあなたへ」 http://dqn.sakusakutto.jp/2011/10/git_push_origin_master.html

ConoHaのVPSでRails5をドメインでデプロイするための最後の設定。ポート番号を使わない方法

ConoHaのVPSでRails5をドメインでデプロイするための最後の設定です。

1. nginxの設定

例えば hello_app という名前のrailsのアプリを作ったとしたら、それがアプリ名です。

このアプリ名を使っていきます。

この記事では仮に 「hello_app」 をアプリ名とします。

まずは

/etc/nginx/conf.d フォルダに、 hello_app.conf

というファイルを作ります。 ファイル名は何でも良いですが、アプリとの関連が分かるようにアプリ名にしておくと良いです。 (nanoエディタ等で作成しましょう)

hello_app.confの内容

upstream hello_app { #ここはアプリ名を使う。
   #転送先(複数serverも列挙可)
   server localhost:3000;
}

server {
   listen 80; #ポート番号
   server_name XXXX; # XXXXはホスト名です。取得したドメイン(○○○.comなど)を記入する。
   root /○○○/○○○/hello_app/public # railsのアプリを置いた場所(ドキュメントルート)を記載。  /public まで書く。(そういうフォルダがある。)

   # 「/~」のリクエストに対する設定
   location / {
      try_files $uri @hello_app; #ここもアプリ名を使用
   }

   # リダイレクトの受け付け
   location / {
      # ヘッダー情報の定義
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;

      # hello_app (サーバーグループ)に転送
      proxy_pass http://hello_app # ここが一番分かりにくいのですが、http://と書いたあとにアプリ名(ここでは hello_app)を書いて下さい。
   }

   #エラーページの設定
   error_page 500 502 503 504 /500.html;
}

2. 不要な設定ファイルをコメントアウト

/etc/nginx/conf.d フォルダの同階層にsample.confというファイルがあるのですが、 上記で作った hello_app.confと競合してしまう可能性があるので、中身をすべて#でコメントアウトしておきましょう。(これが原因で、最初表示されませんでした。)

あとは、Railsのアプリがある階層に行き、

rails s

をすれば、ポート番号なしのドメイン名でアクセス出来ると思います。

以上です。お疲れ様でした。

※今回、セキュリティの設定やテスト環境/production環境の設定などは一切しておりません。 以下の書籍等を参考にしてみて下さい。


参考書籍: Ruby on Rails 5アプリケーションプログラミング 山田 祥寛 https://www.amazon.co.jp/dp/4774188832/ref=cm_sw_r_tw_dp_U_x_9MkAAbM6VRFZ7

参考サイト: 【CentOS 7】Nginx + Unicorn で Rails アプリケーションを本番環境で立ち上げる方法 - Qiita (「Nginx の設定ファイルを作成」)の部分が特に参考になります。

ConoHaのVPSでRails5をIPアドレスでアクセスできるようになった後にお名前.comで取得したドメインでアクセス出来るようにする方法

覚え書きです。

ConoHaのVPSで、IPアドレスでRails5のウェブページにアクセスできるようになった後、今度はお名前.comで取得しているドメインにアクセスできるようにする方法です。

akb428.hatenablog.com

こちらの方法でほぼ大丈夫でした。

1. ドメインを用意

お名前.comで用意しましょう。

2. お名前.comのネームサーバーの設定

f:id:ivoice:20180121010911p:plain

「ネームサーバーの設定」から「DNS関連機能の設定」というものを選びます。 すると、内部ドメイン一覧が表示されるので、割当てたいドメインを選択します。

「次へ進む」を押す。

f:id:ivoice:20180121010918p:plain

そうしたら「DNSレコード設定を利用する」を選択します。

f:id:ivoice:20180121010922p:plain

で、ここが一番注意点で分からなかったところ。

  1. ホスト名は、空欄で、VALUEにConoHaのIPアドレスを入れ、「追加」を押す
  2. ホスト名に「www」 を入れ、VALUEIPアドレスを入れ、「追加」を押す。

この2つが必要です。

※ちなみに、ホスト名をワイルドカード(* ←アスタリスク)にすると、ドメイン名の前が何であれ、アクセスできるようになるそうです。

そうしたらあとは「確認画面に進む」で、登録していきます。

登録するとメールが2通くらい届きます。

あとは、お名前.comのネームサーバーの設定にConoHaのネームサーバー名を入れてあげます。 すみません、これ必要ないです。 

(追記)以下の作業はこれは必要ないそうです。DNSレコード設定をしてしまえば大丈夫だそう。 DNSレコード設定か、以下のネームサーバーの変更、どちらかをすれば大丈夫で、ネームサーバーの変更には3日間くらいかかるので、普通はDNSレコード設定だけすれば大丈夫だったようです。

f:id:ivoice:20180121013609p:plain

このような感じです。 (追記)DNSレコード設定をしていれば上記の作業は必要ないそうです。


あとはConoHaにログインし、Railsを立ち上げ、設定したポート番号で、

ドメイン名:3000 (ポート番号が3000の場合)

のような感じでアクセス出来ます。

以上です。


ここまで来たら、 あとは

qiita.com

ここらへんの方法でポート番号なしのドメインのみでアクセス出来るようになりそうですね。

こちらも参考になりそうです。

marimomemo.hatenablog.jp


※昨日設定したときはドメインでアクセス出来ていたのですが、朝起きてみるとアクセスできなくなっていました。

このサイトにアクセスできません
○○○○○○○○(ドメイン名) のサーバーの IP アドレスが見つかりませんでした。
ERR_NAME_NOT_RESOLVED

こういうエラーです。設定途中なので不安定なんでしょうか。 明日、解決していなかったら問い合わせて聞いてみようと思います。

(追記)ネームサーバーも変更してしまったのが原因でした。 普通はDNSレコード設定の変更だけで良いそうです。 ネームサーバーをお名前.comのものに戻すには、初期化ではなく、

f:id:ivoice:20180122141506p:plain お名前.comのネームサーバー、というのを選び直せば良いそうです。

そのままでも特に問題はないようでしたが、お名前.comのネームサーバーに戻すことにしました。 数時間で反映されて、ドメインでアクセスできるようになりました。