- 投稿日:2019-10-02T22:49:23+09:00
【Rspec】attributes_forってなんだ...
はじめに
ポートフォリオの機能を一通り実装し終えたので、Everyday Railsで勉強をしながらRspecでテストを書き始めました。
モデルスペックを書き終え、コントローラスペックを書いている際に「attributes_for」に出会い、ちょっと詰まったので記事にします。
attributes_forとは
Everyday Railsによると、「プロジェクトファクトリからテスト用の属性値をハッシュとして作成します。」、だそうです。
最初の感想としては、「なんのために???buildでよくない???」でした。
まずは見てみよう
buildとattrubutes_forの違いを以下に示します。
まずはFactoryの中身です。
users.rbFactoryBot.define do factory :user do name "test" sequence(:email) { |n| "test#{n}@test.com"} password "password" end endposts.rbFactoryBot.define do factory :post do content 'test content' association :user end endこれらを用いたbuildとattributes_forで取得するデータの違いが以下の通りです。
build> FactoryBot.build(:post) => #<Post id: nil, content: "test content", user_id: 8, created_at: nil, updated_at: nil>attributes_for> FactoryBot.attributes_for(:post) => {:name=>"test", :email=>"test2@test.com", :password=>"password"}buildはモデルオブジェクト、attributes_forはハッシュとなっていますね。(間違えてたら教えてください)
つまり
パラメータとして値を渡す場合、ハッシュを使って渡すことができます。複数のパラメータを送信する場合に、個々にパラメータ名を付けるのではなく、キーと値を組み合わせたハッシュとして渡せます。
これは実際に見てもらったほうがわかりやすいと思います。
posts_controller_spec.rb#省略 describe "#create" do context "ログインユーザーとして" do before do @user = FactoryBot.create(:user) end it "投稿ができる" do post_params = FactoryBot.attributes_for(:post) sign_in @user expect{ post :create, params: { post: post_params} }.to change(@user.posts, :count).by(1) end end endこのプログラムの、post :create, params: { post: post_params}に注目してください。
これは、post :create, params: { post: {:name=>"test", :email=>"test2@test.com", :password=>"password"} }このプログラムと同義となります。
つまり、POSTメソッドで渡すparamsにpostキーを渡し、そのpostキーのValueをattributes_forの返り値であるハッシュを渡すことで、このように簡潔に書くことができます。(説明下手ですみません...)上記より、buildではなくattributes_forを使用している意味がわかりました。
最後に
私はまだ業界未経験で、なおかつRspecを書き始めて2日目です。
間違えている部分などありましたら、教えてもらえると非常に助かります。以上です。
- 投稿日:2019-10-02T22:16:40+09:00
rbenvでのruby2.6.1インストール時「Agreeing to the Xcode/iOS license requires admin privileges」で失敗
ruby 2.6.1をrbenvを用いてインストールしようとしたときになぜか落ちたので共有。
落ちた箇所
$ rbenv install 2.6.1 Wed Oct 2 15:02:22 2019 Downloading openssl-1.1.0j.tar.gz... -> https://dqw8nmjcqpjn7.cloudfront.net/31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246 Installing openssl-1.1.0j... BUILD FAILED (OS X 10.14.6 using ruby-build 20190423) Inspect or clean up the working tree at /var/folders/y4/jzf9wps144x1w4hp2kwp359xrk7xs7/T/ruby-build.20191002150224.4456 Results logged to /var/folders/y4/jzf9wps144x1w4hp2kwp359xrk7xs7/T/ruby-build.20191002150224.4456.log SIXTY_FOUR_BIT_LONG mode Configured for darwin64-x86_64-cc. Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.こいつが怪しい。
Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.
Xcodeのライセンスがどーのと言われているっぽい...
素直にコマンドを実行
エラー文章通りコマンドを実行する。
$ sudo xcodebuild -license You have not agreed to the Xcode license agreements. You must agree to both license agreements below in order to use Xcode.すると、ずらーーーーーーーーっとライセンスの情報が出ます(文章を共有するのはやめときます)
q
で抜けると、「agree」, 「print」, 「cancel」の3つから操作を求められるので、ターミナル上で「agree」と入力しEnterを押す。By typing 'agree' you are agreeing to the terms of the software license agreements. Type 'print' to print them or anything else to cancel, [agree, print, cancel] agree # agreeを入力してEnter You can view the license agreements in Xcode's About Box, or at /Applications/Xcode.app/Contents/Resources/English.lproj/License.rtfすると、インストールできる。
rbenv install 2.6.1 28.2s Wed Oct 2 15:03:58 2019 ruby-build: use openssl from homebrew Downloading ruby-2.6.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.tar.bz2 Installing ruby-2.6.1... ruby-build: use readline from homebrew Installed ruby-2.6.1 to /Users/xxxxxx/.rbenv/versions/2.6.1なぜライセンス同意をいまさら求められたのかはよくわかりませんが、インストールできたのでOK。
- 投稿日:2019-10-02T21:48:56+09:00
初心者のRails失敗談 ~before_action編~
何が起きたか
公開したサイトのトップページで1ヶ月程度、翻訳機能が動作していませんでした。
サイドメニューから英語、中国語、韓国語等が選べる仕様になっていたのですが、全滅・・・原因
コントローラーで
I18n.locale
を設定できていませんでした。
というのも、該当のコントローラーの親コントローラーにI18n.locale
を取得する処理が書かれていたのですが、それを子コントローラーの方で無きものにしていました。具体的に
before_action :init # 初期化 def init # I18n.localeを設定 I18n.locale = get_locale endこんな感じで親コントローラー内に
before_action
(アクションの前に呼ばれるフィルタを設定するメソッド)の処理が書いてありました。
にも関わらず、、before_action :init # 初期化 def init 他の処理 end子コントローラーの方で、新しく
init
アクションを作ってしまっていました。
子コントローラーのinit
が実行されるので、親コントローラーにあるI18n.locale = get_locale
が実行されません。解決方法
子コントローラーにある
init
を別の名前にする。例えばinit2
とか、なんでもOK振り返り
反省・・・
何かを書き換える時には継承元、継承先をしっかり見る
- 投稿日:2019-10-02T21:30:49+09:00
【Rails】ページ内で読み込みたいCSSを�制御する
ソースコードを見ると
/app/assets/stylesheets/
以下にあるファイルを読み込む記述が自動で書き出されている。
その記述に関してあれこれ変更したかったのでやってみました。一応環境情報を載せておきます。
ruby:2.6.4
rails:5.2.3
目的
1.ページ内に自動記述されるCSSの読み込み順番を変更したい。
2.SASS使用のためのimportさせるファイルは読み込ませたくない。方法
自動記述の制御はある程度
/app/assets/stylesheets/application.scss
内で調整ができる。application.scss(初期状態)/* * This is a manifest file that'll be compiled into application.css, which will include all the files | * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's | * vendor/assets/stylesheets directory can be referenced here using a relative path. | * * You're free to add application-wide styles to this file and they'll appear at the bottom of the | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS | * files in this directory. Styles in this file should be added after the last require_* statement. | * It is generally better to create a new file per style scope. | * *= require_tree . *= require_self */
1.ページ内に自動記述されるCSSの読み込み順番を変更したい。
下部にある
*= require_tree .
から*= require_self
までを変更する。
アセットパイプラインの仕組みにより、ここで読み込みに関して調整可能。
この仕組みはディレクティブと呼ばれている。
(※デフォルトだとアルファベット順?)今回は最下部に記述される
application.css
を最上部にしたいので以下のように記述しました。application.scss(変更後)*= require_self *= require_tree .変更点は、単純に記述の順番を入れ替えただけ。
*= require_tree .
はインクルードさせる記述。
(.
とあるので/app/assets/stylesheets/
を指定していることになる?)
*= require_self
は正直よくわからなかった・・・。勉強します。例えば
hoge01.css
、hoge02.css
...の順で絶対並べたい!という場合は、application.scss*= require_self *= require hoge01.css *= require hoge02.css *= require_tree .のように書いてあげればOK。
ただし、今の状態だと
/app/assets/stylesheets/
以下全てのファイルが自動記述されてしまうので、次で調整する。2.SASS使用のためのimportさせるファイルは読み込ませたくない。
自分はSASSで使用する変数ファイルなどを
/app/assets/stylesheets/partial/
以下に格納しました。
ひとまずサブディレクトリは読み込まれないようにします。application.scss(変更後)*= require_self *= require_directory .
*= require_tree .
→*= require_directory .
に変更するだけ。
*= require_directory .
は/app/assets/stylesheets/pretial/
直下にあるファイルだけ読み込むよ、というもの。自動でやってくれるのはとても便利ですので、なおさら制御方法は知っておかなきゃいけないなと痛感。
まだまだRails開発を始めたばかりなので、今後深掘りしていこうと思います。参考サイト
RailsでCSSの読み込む順番を制御する方法 - Qiita
Rails 使用するCSSを指定する | | KeruuWeb
Railsのマニフェストファイルを使ったJsとStylesheetの呼び出し - Qiita
- 投稿日:2019-10-02T20:47:47+09:00
[質問です。]rubyのapiの叩き方について
rubyでapiを叩きたい
現在プログラミング歴1ヶ月でlinebotを作成しながら勉強しています。
ぐるなびAPIをlinebotに使用したい
ぐるなびAPIをlinebotに使用する所でつまづいており、皆様にご質問があります。
下記エラーが解決出来ません
NoMethodError (undefined method `sample' for nil:NilClass):該当コードは
linebot_controller.rbevents.each { |event| if event.message['text'] != nil place = event.message['text'] #ここでLINEで送った文章を取得 result = `curl -X GET https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid=ffb92f0f997a628153ecfa407099fe9b&category_s=RSFST08008&category_s=RSFST08009&#{place}` else latitude = event.message['latitude'] longitude = event.message['longitude'] result = `curl -X GET https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid=ffb92f0f997a628153ecfa407099fe9b&category_s=RSFST08008category_s=RSFST08009&latitude=#{latitude}longitude=#{longitude}`#ここでぐるなびAPIを叩く end hash_result = JSON.parse result #レスポンスが文字列なのでhashにパースする shops = hash_result["rest"] #ここでお店情報が入った配列となる shop = shops.sample #任意のものを一個選ぶhash_result = JSON.parse result 部分まではしっかり値が入っているのですが、
shops = hash_result["rest"] ←この部分がnilで返ってきてしまいエラーを吐き出してしまいます。
文法のミス等自分なりにapiを叩く記述を参考にしながら行なったのですが解決出来ません。
皆様のお力をお貸しいただけると幸いです。以下参考記事
https://qiita.com/NoharaMasato/items/6fb1ac277c965905e019
- 投稿日:2019-10-02T20:47:47+09:00
(質問です)rubyのapiの叩き方について
rubyでapiを叩きたい
現在プログラミング歴1ヶ月でlinebotを作成しながら勉強しています。
ぐるなびAPIをlinebotに使用したい
ぐるなびAPIをlinebotに使用する所でつまづいており、皆様にご質問があります。
下記エラーが解決出来ません
NoMethodError (undefined method `sample' for nil:NilClass):該当コードは
linebot_controller.rbevents.each { |event| if event.message['text'] != nil place = event.message['text'] #ここでLINEで送った文章を取得 result = `curl -X GET https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid=ffb92f0f997a628153ecfa407099fe9b&category_s=RSFST08008&category_s=RSFST08009&#{place}` else latitude = event.message['latitude'] longitude = event.message['longitude'] result = `curl -X GET https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid=ffb92f0f997a628153ecfa407099fe9b&category_s=RSFST08008category_s=RSFST08009&latitude=#{latitude}longitude=#{longitude}`#ここでぐるなびAPIを叩く end hash_result = JSON.parse result #レスポンスが文字列なのでhashにパースする shops = hash_result["rest"] #ここでお店情報が入った配列となる shop = shops.sample #任意のものを一個選ぶhash_result = JSON.parse result 部分まではしっかり値が入っているのですが、
shops = hash_result["rest"] ←この部分がnilで返ってきてしまいエラーを吐き出してしまいます。
文法のミス等自分なりにapiを叩く記述を参考にしながら行なったのですが解決出来ません。
皆様のお力をお貸しいただけると幸いです。以下参考記事
https://qiita.com/NoharaMasato/items/6fb1ac277c965905e019
- 投稿日:2019-10-02T20:34:35+09:00
presence メソッド
- 投稿日:2019-10-02T19:22:48+09:00
[初心者]Rails6にbootstrap4を導入する
Ruby on railsを学び始めて約2ヶ月、
初めてbootstrapを導入したので、記事を作ってみました。
環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.14.6 BuildVersion: 18G95 $ ruby -v ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-darwin18] $ rails -v Rails 6.0.0
目次
bootstrap
のgem
を追加applicationファイル
を編集index.html.erb
を編集bootstrap
が導入されているかを確認
1.bootstrap gemを追加
Gemfileに以下を追加
Gemfile~ gem 'bootstrap', '~> 4.1.1' gem 'jquery-rails' ~
terminal
でbundle install
を実行
(ローカルでgemを管理している場合は、bundle install --path=vendor/bundle
で実行)これで、プロジェクト内にbootstrapのgemが追加されました。
2.applicationファイルを編集
2.1 application.cssの編集
app>assets>stylesheets>application.cssをエディタで開き、
@import "bootstrap";
を追加application.css~ @import "bootstrap"; ~次に拡張子を
.css
から.scss
へ変更
application.css → application.scss2.2 application.jsの編集
app>assets>javascript>application.jsをエディタで開き、
//= require bootstrap
を追加
(フォルダ、ファイルがなければ作成)
bootstrapはjqueryとpopperに依存しているらしいので導入application.js//= require jquery3 //= require popper //= require bootstrap-sprockets3.index.html.erb を編集
適当なcontrollerに以下のコードを追加
app>assets>views>コントローラ名>index.html.erb
このコードはbootstrapのサイトにあるテストコードです。index.html.erb<a class="btn btn-primary" href="#" role="button">Link</a> <button class="btn btn-primary" type="submit">Button</button> <input class="btn btn-primary" type="button" value="Input"> <input class="btn btn-primary" type="submit" value="Submit"> <input class="btn btn-primary" type="reset" value="Reset">4.動作確認
下準備は整いました。
bundle exec rails s
でローカルにサーバーを立ち上げます。
ブラウザにlocalhost:3000/コントローラ名/index
を入力し、画面を確認してください。
以下の表示になっていれば完了です。
- 投稿日:2019-10-02T18:01:16+09:00
いいね機能の実装
やりたいこと
投稿に対してユーザーがいいねする機能を実装したい!
今やどのWebサービスにも搭載している機能ですね。
Rails勉強中の方は是非この記事を読んで、
やり方を理解して実装できるようになれるようになってください!!
わからないことがあればコメントお願いします!!やり方
前提
userとpostテーブルがあり、userが親、postが子の親子関係です。
モデル、ルーティング、コントローラー、ビューをそれぞれ説明していきます。
モデル
モデル作成
まずFavoriteモデルを作成します
ターミナルから作成しましょうターミナルrails g model Favoriteモデル編集
その作成されたモデルのファイルにアソシエーションの関係を追記していきましょう
app/models/user.rbclass User < ApplicationRecord has_many :posts, dependent: :destroy has_many :favorites, dependent: :destroy end
has_many :posts, dependent: :destroy
has_many :favorites, dependent: :destroy
を追記しましょう
has_many
は1つのuserは複数のpost、favoriteを持っているような時に記載します
dependent: :destroy
は親のレコードを削除した時に
関連している子供のレコードも全て削除するための記述です。
この記述がある時は、あるuserが削除されるとそのuserが持っているpostを全て削除されます。app/models/post.rbclass Post < ApplicationRecord belongs_to :user has_many :favorites, dependent: :destroy end
belongs_to :user
has_many :favorites, dependent: :destroy
を追記しましょう。
belongs_to
は1つのpostは1つはuserを持っているような時に記載します。app/models/favorite.rbclass Favorite < ApplicationRecord belongs_to :user belongs_to :post end
belongs_to :user
belongs_to :post
を追記しましょうマイグレーションファイルの編集
次は、モデルを編集した後はテーブルを作成しましょう
以下の3つのマイグレーションファイルにそれぞれ追記していきましょうdb/migrante/******_create_favorites.rbclass CreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| t.integer :user_id t.integer :post_id t.timestamps end end end
t.integer :user_id
t.integer :post_id
を追記しましょう。マイグレーションファイル編集後は
bundle install
をしましょう。ターミナルbundle install
bundle install
が成功するとテーブルが作成されます。ルーティング
まず、ルーティングを以下を追記しましょう。
config/routes.rbresources :posts do resource :favorites, only: [:create, :destroy] endターミナル上で
rails routes
を行いルーティングが通っているか確認しましょうコントローラー
まずコントローラーを作成しましょう
ターミナルrails generate controller Favoritesfavorites_controller
作成されたコントローラーを編集していきます
いいねボタンが押された時に繋がるアクションを記述していきましょうcreateアクション
app/controllers/favorites_controllerdef create @post_favorite = Favorite.new(user_id: current_user.id,post_id: params[:post_id]) @post_favorite.save result = [done: "save",user_id: current_user.id, post_id: params[:post_id]] redirect_to post_path(params[:post_id]) enddestroyアクション
app/controllers/favorites_controllerdef destroy @post_favorite = Favorite.find_by(user_id: current_user.id, post_id: params[:post_id]) @post_favorite.destroy result = [done: "destroy",user_id: current_user.id, post_id:params[:post_id]] redirect_to post_path(params[:post_id]) endビュー
いいねボタンを投稿の詳細画面に実装していきます
まず、ログインしているユーザーが投稿に対していいねしているかどうかで表示内容を変更します。app/models/post.rbdef favorited?(user) favorites.where(user_id: user.id).exists? endモデルにいいねしているかどうかを判定するメソッドを記入します
if @post.favorite?(current_user) #ユーザーがいいねしていた時の処理(destroyアクションへのリンク) else #ユーザーがいいねしていない時の処理(createアクションへのリンク) end実際にビューファイルに以下の記述を追加していきましょう
app/views/posts/show.html.erb<%if @post.favorite?(current_user)%> <%= link_to post_favorites_path(@post), method: :delete do %> <span style="color:red;">❤︎</span> <%end%> <%else%> <%= link_to post_favorites_path(@post), method: :post do %> <span>❤︎</span> <%end%> <%end%>疑問、気になるところございました、コメントください!!
- 投稿日:2019-10-02T16:24:35+09:00
cloud9 環境 で rails 5.2.3を初めて設定してみた。
概要
Rubyを学び始めた初学者です。clou9でruby開発環境を整えるまで2日かかってしまいました。rails6.0.0をインストールしてもrailsサーバーが起動できなかった(yarnインストールができず、諦めました。)ため、rails5.2.3で構築してみましたよ。初投稿。
間違っている所などありましたら、ご指摘頂けると嬉しいです。前提条件
amazon web serviceアカウントを持っている方
cloud9環境での開発を考えている方環境
ruby 2.6.5
rails 5.2.3
sqlite3 3.7.17ruby 2.6.5 のインストール
environmentディレクトリにて、コードの実行をする。
インストール可能なruby一覧情報
rvm list know
rubyのインストール
rvm install 2.6.5
複数インストールしたrubyから、選択する
rvm use 2.6.5
インストールされているrubyの内、どれが使われているか確認
rvm list
インストールされているrubyを、選択して削除
rvmsudo rvm remove 2.6.5
インストールした複数のrubyから、デフォルトとして設定
rvm --default use 2.6.5
rails 5.2.3のインストール
environmentディレクトリにて、コードの実行をする。
```gem install rails --version="5.2.3"railsプロジェクトの作成
『プロジェクト名』のフォルダを作成。
以下、コマンドでディレクトリ移動。
cd 『プロジェクト名』
rails _5.2.3_ new フォルダ名
を入力。
『フォルダ名』ディレクトリへ移動。
cd 『フォルダ名』
bundleのインストール
bundle install
sqlite3の更新設定
gemfile→の中→9行目あたりの
sqlite3
の後に,'~>1.3.6'
と入力ターミナルにて、
bundle update
rails db:create
と入力サーバーの起動
ターミナルにて、
rails s
と入力上部タブ『preview』から『preview runnning applecation』を選択
URLを確認。rails スタートの画面になっていれば成功。
- 投稿日:2019-10-02T15:56:51+09:00
Deviseを入れた後、コンソールからのUser.firstやUser.all等がArgmentErrorになる
結論
Userモデルから
password_digestカラム
を削除すると解消する。起こったこと
Deviseを入れた後、コンソールからのUser.firstやUser.all等が下記のようにArgmentErrorになる
irb(main):001:0> User.all User Load (1.8ms) SELECT "users".* FROM "users" LIMIT ? [["LIMIT", 11]] Traceback (most recent call last): ArgumentError (wrong number of arguments (given 0, expected 1)) irb(main):002:0> User.find(1) User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] Traceback (most recent call last):下記のissueにある通り、DeviseでUserモデルをセットアップした時に、既にUserモデルに
password_digestカラム
が存在すると、上記のエラーが出ます。参考
https://github.com/plataformatec/devise/issues/今回は既にUserモデルを作っていて、後からDeviseを導入したのでおそらくDeviseの
encrypted_passwordカラム
とバッティングして発生していると思われる。なので、Userモデルから
password_digestカラム
を削除すると解消しました。
- 投稿日:2019-10-02T15:25:37+09:00
Rails スクレイピングでデータを取得(getメソッド・searchメソッド編)備忘録
スクレイピングとは
- 例えば、以下のようなHTMLのサイトがあった場合
index.html<ul> <li>TEST1</li> <li>TEST2</li> <li>TEST3</li> </ul>
<ul><li>
の中にある「TEST1, TEST2, TEST3」等の値を取り出すことを言う。(ウェブサイト上のHTMLからある特定のデータを抜き出す処理のこと)Mechanize
- Mechanizeはスクレイピングを行うためのGemである。
- Mechanizeクラスが使えるようになる。
- Mechanizeクラスにはスクレイピングするための様々なメソッドが用意されている。
GemfileにMechanizeを追記(Railsの場合)
Gemfile# 省略 gem 'mechanize'bundle installすればOK
Mechanizeクラスで使うメソッドの紹介
HTML情報から指定のタグ要素の情報を検索する
● searchメソッド
- getメソッドで取得したページの情報が入ったオブジェクトに対して使用する。
- 該当するHTMLのタグ要素が1つでも、返り値は配列の形式で返ってくる。
使い方
elements = Mechanize::Pageオブジェクト.search('セレクタ')あるウェブページからh2要素のHTMLの情報を取得する場合
scraping.rbagent = Mechanize.new page = agent.get("http://sample.com/") elements = page.search('h2') # h2要素を検索 puts elements
- 出力結果(例)
<h2 class="entry-title index-entry-title"> <a href="/products/1" title="Single Post">sample1</a> </h2> <h2 class="entry-title index-entry-title"> <a href="/products/2" title="Single Post">sample2</a> </h2> <h2 class="entry-title index-entry-title"> <a href="/products/3" title="Single Post">sample3</a> </h2> #以下略h2要素の下のa要素のHTML情報を取得してみる
scraping.rbagent = Mechanize.new page = agent.get("http://sample.com/") elements = page.search('h2 a') # h2要素の下のa要素を検索 puts elements
- 出力結果(例)
<a href="/products/1" title="Single Post">sample1</a> <a href="/products/2" title="Single Post">sample2</a> <a href="/products/3" title="Single Post">sample3</a> <a href="/products/4" title="Single Post">sample4</a> # 以下略このように、該当するHTMLのタグ要素全てが取得される。
- 以下のようにするとsearchメソッドの返り値が配列の形式になっていることが確認できる。
test_scraping.rbrequire 'mechanize' agent = Mechanize.new page = agent.get("http://sample.com/") elements = page.search('h2 a') # h2要素の下のa要素を検索 puts elements[0]
- 出力結果
ターミナル<a href="/products/1" title="Single Post">Sample1</a>以上のように返ってきた値の1番目の要素を取り出すことができるので配列の形式で返ってきていることがわかる。
まとめ
以上でmechanizeを使用したメソッドのうちgetメソッドとsearchメソッドの2つを紹介しましたが今日は時間切れなので後日、他の使える便利なメソッドを紹介したいと思う。
- 投稿日:2019-10-02T14:55:55+09:00
bundle install時にインストール先のpathを変える
bundle install時にインストール先のpathを変える
(anyenv, rbenv利用)
deviseインストール。
ログを見ると、.anyenv/envs/rbenv/以下へdeviseがインストールされ、実行されている。
bundle install時にpathを指定しないと、rbenvを利用している場合は.anyenv/envs/rbenv/以下にインストールされる。
参考
https://qiita.com/chro96/items/35f67767d0b511939feadeviseのファイルを編集するのに.anyenv/envs/rbenv/以下だとやりづらいため、プロジェクト以下にインストールしたい。
そのため、bundle install時にpathを指定する。
-j4は bundle install を並列処理するコマンド。
bundle install が早くなる。
https://qiita.com/camelmasa/items/5ca27ab398f105f86c76$ bundle install -j4 --path .bundleこれでプロジェクト内に、.bundleというディレクトリが作成され、gemがインストールされ、.bundle/以下にあるファイルで実行されることを確認。
- 投稿日:2019-10-02T12:21:19+09:00
Rails6 のちょい足しな新機能を試す87(Time#advance編)
はじめに
Rails 6 に追加された新機能を試す第87段。 今回は、
Time#advance
編です。
Rails 6 では、 1001/03/07 以前のTime#advance
の計算が正確になりました。Ruby 2.6.4, Rails 6.0.0 Rails 5.2.3 で確認しました。
$ rails --version Rails 6.0.0今回は、ちょっとわざとらしいですが、2009年4月1日の1200年前に即位した天皇を検索してみましょう。
プロジェクトを作る
rails new rails_sandbox cd rails_sandbox
Emperor モデルを作る
name
とenthroned_at
(即位した年) をもつEmperor
モデルを作ります。bin/rails g model Emperor name enthroned_at:datetimeseed データを作る
seed
データを作ります。db/seeds.rbEmperor.create( [ { name: '桓武天皇', enthroned_at: Time.utc(781, 4, 3) }, { name: '平城天皇', enthroned_at: Time.utc(806, 3, 17) }, { name: '嵯峨天皇', enthroned_at: Time.utc(809, 4, 1) }, { name: '淳和天皇', enthroned_at: Time.utc(823, 4, 16) }, { name: '仁明天皇', enthroned_at: Time.utc(833, 2, 28) } ] )マイグレーションを行い seed データを登録する
$ bin/rails db:create db:migrate db:seed
rails console で確認する
enthroned_at
が 2009年4月1日の 1200年前に即位した天皇を検索してみます。「2009年4月1日の 1200年前」は、
Time.utc(2009, 4, 1).advance(years: 1200)
で求めることができます。irb(main):001:0> Emperor.where(enthroned_at: Time.utc(2009, 4, 1).advance(years: -1200)) Emperor Load (0.3ms) SELECT "emperors".* FROM "emperors" WHERE "emperors"."enthroned_at" = $1 LIMIT $2 [["enthroned_at", "0809-04-01 00:00:00"], ["LIMIT", 11]] => #<ActiveRecord::Relation [#<Emperor id: 3, name: "嵯峨天皇", enthroned_at: "0809-04-01 00:00:00", created_at: "2019-09-21 21:49:24", updated_at: "2019-09-21 21:49:24">]>嵯峨天皇が検索できました。
Rails 5.2.3 では
「2009年4月1日の 1200年前」が 809年4月5日になってしまうため、期待した結果が得られません
irb(main):001:0> Emperor.where(enthroned_at: Time.utc(2009, 4, 1).advance(years: -1200)) Emperor Load (0.5ms) SELECT "emperors".* FROM "emperors" WHERE "emperors"."enthroned_at" = $1 LIMIT $2 [["enthroned_at", "0809-04-05 00:00:00"], ["LIMIT", 11]] => #<ActiveRecord::Relation []>試したソース
試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try087_time_advance参考情報
- 投稿日:2019-10-02T12:07:01+09:00
Railsアプリ〜デプロイへの道〜その②Ruby・MySQLインストール編【ConoHa VPS・CentOS・Capistrano3・Nginx・Unicorn】
Railsアプリケーションをデプロイした時の手順をまとめた記事の第2弾です。
今回はRubyおよびMySQLのインストール・設定の手順をまとめました。
前回同様こちらの記事がベースとなっています。
https://qiita.com/ryo2132/items/f62690f0b16ec11270fe〈前回記事〉
Railsアプリ〜デプロイへの道〜その①リモートサーバーへのSSH接続編開発環境
・Mac OS
・Rails 5.2.3
・Ruby 2.5.1
・ConoHa VPS
・CentOS 7.6
・Capistrano3
・Nginx
・UnicornRubyのインストール
ConoHa VPSにRubyをインストールしていきます。
1.Gitインストール
まずGitをインストールします。
$ sudo yum -y install git $ git --version # version名出力されればOK2.rbenvインストール
続いてrbenvをインストール。
rbenvはRubyのバージョン管理ツールです。$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenvruby-burildインストール
こちらもRubyをインストールするために必要になります。
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build3.rbenv設定
rbenvコマンドを使えるようにするためにbash_profileに以下の内容を追加します。
# PATHにrbenvコマンドを追加 $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile # rbenvの初期化 $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile # bashの再読込 $ source ~/.bash_profile # rbenvのバージョン確認 バージョンが出ればOK $ rbenv -vこれでRubyインストールの準備は完了です。
いよいよRubyをインストールします。4.Rubyインストール
ローカルで使用中のRubyバージョンを確認
サーバーにインストールする前に、開発で使用したRubyのバージョンを確認します。ローカル
$ ruby -vローカルと同じバージョンのRubyをインストール
サーバー
$ rbenv install 2.5.1 # globalで使用するrubyの設定 $ rbenv global 2.5.1 # rbenvの再起動? $ rbenv rehash # rubyのバージョン確認 $ ruby -v5.bundleインストール
Gemの管理ツールであるbundlerをインストールします。
bundlerのバージョンを開発したRailsアプリのGemfile.lockのものと合わせる必要があります。
バージョンが合っていないとデプロイ時にエラーが発生します。
参考:https://qiita.com/MotohiroSiobara/items/c0d343a160cffc2902efRailsアプリのGemfile.lockを確認
BUNDLED WITH 2.0.1サーバー
同じバージョンのbundlerをインストール。$ gem install bundle -v 2.0.16.関連パッケージインストール
必要なパッケージを諸々インストール
これらがないとデプロイ時にエラー起こします。<参考>
https://teratail.com/questions/13430
https://qiita.com/jaxx2104/items/2277cec77850f2d83c7aサーバー
#gcc-c++インストール $ sudo yum install gcc-c++ #node.jsインストール $ sudo yum install nodejs npm --enablerepo=epel #yarnインストール $ sudo npm install -g yarnMySQL
1.事前準備:MariaDBの削除
CentOS7系では標準でMariaDB(MySQL互換のDB)がインストールされている場合があるので、MySQLと競合しないようMariaDBを削除します。
参考:https://qiita.com/miqpim/items/5c519a9979d9b269d47e
サーバー
$ rpm -qa | grep maria # mariaDBが存在するか確認 $ sudo yum remove mariadb-libs # 本体削除 $ sudo rm -rf /var/lib/mysql # データ削除rmコマンドのオプションについてはこちらをご覧ください。
参考:https://eng-entrance.com/linux_command_rm2.MySQLのリポジトリを登録
Mysql公式のYumリポジトリをインストールします。
最新版はMysql公式で確認できます。サーバー
〈参考〉
https://qiita.com/rutko/items/56a33d1ecd70c0480202
https://qiita.com/nooboolean/items/7efc5c35b2e95637d8c1CentOSのバージョンの確認
$ cat /etc/redhat-releaseリポジトリのインストール
yumコマンドのlocalinstallオプションを使うことでリモートにあるrpmファイルをインストールすることができます。
rpmコマンドを使ってのインストールも可能ですが、依存関係とかを考慮したインストールまではしてくれないので、yumでインストールしましょう。
URLはリモートにあるrpmファイルをインストールするためのもので、公式サイトのリポジトリを、http://dev.mysql.com/get/
の後に付け加えて完成です。(お使いのOSに合わせたものを選んでください)詳しくはこちらの記事をご覧ください。
https://qiita.com/nooboolean/items/7efc5c35b2e95637d8c1$ sudo yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpmリポジトリの確認
/etc/yum.repos.d配下に、mysql-community-source.repoとmysql-community.repoというリポジトリが作成されてるはずです。
$ cd /etc/yum.repos.d/ $ ls mysql-community-source.repo mysql-community.repoこのリポジトリが作成されて入れば、リポジトリの追加の確認は完了
インストールできたか確認
$ yum repolist all | grep mysql mysql-connectors-community/x86_64 MySQL Connectors Community 有効: mysql-connectors-community-source MySQL Connectors Community - So 無効 mysql-tools-community/x86_64 MySQL Tools Community 有効: mysql-tools-community-source MySQL Tools Community - Source 無効 mysql55-community/x86_64 MySQL 5.5 Community Server 無効 mysql55-community-source MySQL 5.5 Community Server - So 無効 mysql56-community/x86_64 MySQL 5.6 Community Server 無効 <-ここ注目 mysql56-community-source MySQL 5.6 Community Server - So 無効 mysql57-community/x86_64 MySQL 5.7 Community Server 有効: <-ここ注目 mysql57-community-source MySQL 5.7 Community Server - So 無効(環境によっては有効がenabled、無効がdisabledと表示される) 上記の例では、5.7が有効、5.6が無効になっています。 このままインストールすると、有効になっている5.7がインストールされてしまうので、5.6をインストールするには有効無効の切り替えをします。 この切り替えをするためにはyumの設定変更用のyum-utilsパッケージが必要なので、インストールされていない場合はインストールします。
$ yum list installed | grep yum-utils #yum-utilsがインストールされているか確認 $ yum -y install yum-utils #入ってなければyum-utilsをインストールする $ yum-config-manager --disable mysql57-community #5.7を無効に設定 $ yum-config-manager --enable mysql56-community #5.6を有効に設定設定ができているか再度確認。
$ yum repolist all | grep mysql mysql-connectors-community/x86_64 MySQL Connectors Community 有効: mysql-connectors-community-source MySQL Connectors Community - Sou 無効 mysql-tools-community/x86_64 MySQL Tools Community 有効: mysql-tools-community-source MySQL Tools Community - Source 無効 mysql55-community/x86_64 MySQL 5.5 Community Server 無効 mysql55-community-source MySQL 5.5 Community Server - Sou 無効 mysql56-community/x86_64 MySQL 5.6 Community Server 有効: mysql56-community-source MySQL 5.6 Community Server - Sou 無効 mysql57-community/x86_64 MySQL 5.7 Community Server 無効 mysql57-community-source MySQL 5.7 Community Server - Sou 無効5.6が有効になっていればOK。
#バージョン確認 $ yum info mysql-community-server # インストール $ sudo yum install mysql-community-server mysql-develmysql-develは必要です。
ないとデプロイ時にエラーが出ます。
参考:https://teratail.com/questions/181707# 確認。バージョン出ればOK $ mysqld --versionMysqlの起動/自動起動設定
起動
$ sudo systemctl start mysqld.service #起動自動起動設定
$ sudo systemctl enable mysqld.service #自動起動 ON $ systemctl disble mysqld #自動起動 OFF自動起動になっているか確認
$ systemctl is-enabled mysqld mysqld.service is not a native service, redirecting to /sbin/chkconfig. Executing /sbin/chkconfig mysqld --level=5 enabledenabledになっていれば自動起動 ONに設定されています。
基本操作
$ sudo systemctl start mysqld.service #起動 $ systemctl stop mysqld #停止 $ systemctl status mysqld #ステータス確認 $ systemctl restart mysqld #再起動ちなみに、mysqldのdはデーモン (daemon)のdらしいです。
デーモンについてはこちらの記事をご覧ください。
https://wa3.i-3-i.info/word11000.html簡単に言うと「いつでも動けるようにスタンバイしてる常駐プログラム」だそうです。
3.パスワード、セキュリティ設定
続いてMySQLの設定をしていきます。
今回の山場です。
参考:https://weblabo.oscasierra.net/mysql-57-init-setup/ログインするために、まず自動生成された初期パスワードを確認します。
$ sudo cat /var/log/mysqld.log | grep password 2017-12-31T11:31:07.946947Z 1 [Note] A temporary password is generated for root@localhost: .7ogGO4yokDh # 「.7ogGO4yokDh」の部分が初期パスワードです確認できたらmysql_secure_installationで初期設定を行います。 以下対話形式で進むので適宜コマンド入力してください。
$ mysql_secure_installation Securing the MySQL server deployment. Enter password for user root: # ログファイルから取得した初期パスワードを入力します The existing password for the user account root has expired. Please set a new password. New password: # root ユーザの新規パスワードを入力します Re-enter new password: # 確認用にもう一度入力します The 'validate_password' plugin is installed on the server. The subsequent steps will run with the existing configuration of the plugin. Using existing password for root. Estimated strength of the password: 100 Change the password for root ? ((Press y|Y for Yes, any other key for No) : y By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? (Press y|Y for Yes, any other key for No) : y # 匿名ユーザーアカウントを削除 Success. Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y # ローカルホスト以外からアクセス可能な root アカウントを削除 Success. By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y # test データベースの削除 - Dropping test database... Success. - Removing privileges on test database... Success. Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y Success. All done!4.日本語化
日本語を扱うために文字コードを設定します。
日本語の文字コードはutf8に設定すると思いますが、utf8mb4は絵文字に対応した文字コードなので、僕はutf8ではなくutf8mb4で設定しています。現状、問題なく使えています。
〈参考〉
https://qiita.com/okamu_/items/5eb81688849fbe351350
https://qiita.com/jkr_2255/items/74fc79e764378b59355a$ sudo vi /etc/my.cnf #ファイル内の末尾に以下を追記 [mysqld] character-set-server=utf8mb4 [client] default-character-set=utf8mb4 #再起動 $ sudo systemctl restart mysqld.service #文字コード確認 $ mysql -u root -p $ show variables like "chara%";utf8mb4になってたらOK!
5.Time-zone設定
〈参考〉
https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html
https://agohack.com/mysql-change-timezone/現在のタイムゾーンを確認
$ show variables like '%time_zone%'; system_time_zone : UTC time_zone : SYSTEMタイムゾーンデータの確認
$ select * from mysql.time_zone;空の場合は、データをインポートする。
タイムゾーンのインポート
$ /usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo > ~/timezone.sql # passwordを聞かれるのでmysqlのパスワードを入力 $ mysql -u root -p -Dmysql < ~/timezone.sql設定の追加
$ sudo vi /etc/my.cnf # 末尾に以下を追加 [mysqld] default-time-zone = 'Asia/Tokyo'再起動
$ sudo systemctl restart mysqld.service確認
mysql > show variables like '%time_zone%'; # 以下表示が出ればOK +------------------+------------+ | Variable_name | Value | +------------------+------------+ | system_time_zone | JST | | time_zone | Asia/Tokyo | +------------------+------------+ 2 rows in set (0.00 sec)MySQLの自動起動設定
サーバーの再起動の際にも、mysqlが自動的に起動するよう設定します。chkconfig mysqld onまとめ
以上、Railsアプリ〜デプロイへの道〜その②Ruby・MySQLインストール編でした。
次回はいよいよCapistrano3・Nginx・Unicornの設定です。(予定)
- 投稿日:2019-10-02T09:46:46+09:00
canvasで描いた絵のURLをDBに保存する
概要
私は9月ごろから独学でRuby on Railsを始めたのですが、題名の通りcanvasで描いた絵をURLに変換してDBに保存する際に数日詰まったので自分への戒めのために今回の記事を書く運びとなりました。
詰まったところ
ArgumentError (When assigning attributes, you must pass a hash as an argument.):
ハッシュにしてから受け渡してください的なエラーが出る。
受け渡したデータ
JavaScriptでcanvasのデータをURL化しているため、そのままJavaScriptでPOSTしました。
こんなかんじ//変数imageにはcanvasのURLが入っています function send_url(image){ var form = document.createElement('form'); var request = document.createElement('input'); form.method = 'POST'; form.action = 'save'; request.type = 'hidden'; request.name = 'text'; request.value = image; form.appendChild(request); document.body.appendChild(form); form.submit(); }受け取り側はこのようになっています
private def post_params params.require(:text) end endこの形式で受け取るとpost_paramsは送信されてきた文字列だけをデータに持ちます。
修正後
先ほどの関数post_paramsを次のように書き換えました
def post_params img = params.require(:text) hash_url = {"image_url" => img} return hash_url end力技です。
最後に
セキュリティなどの観点で見てこれが大丈夫なやり方なのかはわかりませんが、とりあえずこのハッシュにしたデータを渡すことで無事URLをDBに渡すことができました。
- 投稿日:2019-10-02T07:59:27+09:00
【Rails on Docker on Heroku】ActiveStorage + Cloudinaryで画像を管理するメモ
はじめに
この記事はRuby on RailsのActiveStorageとCloudinaryを使って画像を管理するアプリを作るためのメモです。PaaSとしてHerokuを使います。
ActiveStorageはRails 5.2以上で動作するクラウドストレージサービスへのファイルのアップロードやActiveRecordオブジェクトへのファイルのアタッチをやってくれる便利なモデルです。
Cloudinaryは画像や動画のCDNや編集の機能を有するSaaSです。Herokuのadd-onsとしても存在しています。
この記事のゴール
この記事では、Heroku上でユーザー名とプロフィール写真を管理するRuby on Railsアプリケーション(on Docker)をHeroku上で動作させることをゴールにします。DB/StorageはHerokuのadd-onsからPostgres/Cloudinaryを使います。
前提
- Rails on Dockerの準備ができていること --> Quickstart: Compose and Rails | Docker Documentation
- Herokuのアカウントが準備できていること
メモ
1. ActiveStorageのアプリを作る
こちらの記事が参考になりました。
【Rails 5.2】 Active Storageの使い方 - QiitaまずファイルをアタッチするモデルとしてUserモデルをscaffoldで作っておきます。
$ docker-compose run --rm web rails g scaffold user name:string $ docker-compose run --rm web rails db:migrate続いて、ActiveStorageをインストール。
$ docker-compose run --rm web rails active_storage:install $ docker-compose run --rm web rails db:migrateActiveStorageはモデルに
has_one_attached
を定義するだけでファイルを扱えるようになる優れものです。app/models/user.rbclass User < ApplicationRecord has_one_attached :photo endこれで
photo
という名前のファイルをActiveStorageが勝手に管理してくれます。
ファイルのアップロードと参照ができるようにview/controllerも手直ししておきます。app/controllers/users_controller.rbdef user_params # photoの登録を許可 params.require(:user).permit(:name, :photo) endapp/views/users/_form.html.erb<!-- 以下をいい感じのところに追加 --> <div class="field"> <%= form.label :photo %> <%= form.file_field :photo %> </div>app/views/users/show.html.erb<!-- 以下をいい感じのところに追加 --> <div> <% if @user.photo.attached? %> <%= image_tag @user.photo %> <% end %> </div>これで
User
モデルでphoto
としてファイルを管理できるようになりました。
この段階ではphoto
として登録されるファイルはstorage/
に保存されていきます。これはconfig/environments/development.rbconfig.active_storage.service = :localconfig/storage.ymllocal: service: Disk root: <%= Rails.root.join("storage") %>で定義されています。
2. Herokuの準備
HerokuはHeroku CLIで操作していきます。まずはadd-onsでpostgresとcloudinaryの準備が必要です。まずHerokuにログインしてアプリを作成します。
$ heroku login $ heroku create app-nameこのアプリに対してpostgresとcloudinaryのadd-onsを追加してきます。postgresは無料のhobby-dev、cloudinaryも無料のstarterというプランを使っていきます。cloudinary:starterはクレカ登録してないと使えないみたいですね。
$ heroku addons:create heroku-postgresql:hobby-dev $ heroku addons:create cloudinary:starter3. ActiveStorageとCloudinaryを連携させる
ActiveStorageとCloudinaryを連携させるためにGitHub - 0sc/activestorage-cloudinary-serviceを利用します。
READMEの通りにやっていけばOKです!
Gemfilegem 'cloudinary', require: false gem 'activestorage-cloudinary-service'$ docker-compose buildCloudinaryと連携するための
cloud_name
、api_key
、api_secret
の情報をRailsアプリに登録してきます。これらの情報はHerokuサイトでOverviewのところから各アドオンのサイトにリンクされているんですが、リンク先のCloudinaryのDashboardに情報が載ってます。
Rails5.2以降であればcredentials
を利用しているかと思いますので、そちらの方法で。$ docker-compose run --rm -e EDITOR="vim" web rails credentials:editcloudinary: cloud_name: xxxxxxxxxx api_key: xxxxxxxxxx api_secret: xxxxxxxxxx※vimがないとか言われる場合は【Rails 5.2.2】Rails on Dockerでcredentialsをeditしたい - Qiitaあたりを参考にしていただけますと!
この設定をconfig/storage.yml
から呼び出します。config/storage.yml# 以下を追加 cloudinary: service: Cloudinary cloud_name: <%= Rails.application.credentials.dig(:cloudinary, :cloud_name) %> api_key: <%= Rails.application.credentials.dig(:cloudinary, :api_key) %> api_secret: <%= Rails.application.credentials.dig(:cloudinary, :api_secret) %>そして、
config/environments/development.rb
で指定されているconfig.active_storage.service
も書き換えます。config/environments/development.rb# config.active_storage.service = :local config.active_storage.service = :cloudinary本当は
production.rb
を書き換えて、heroku側のconfigもRAILS_ENV=production
とするべきなのですが、今回のメモはお試しなのでdevelopmentで進めますね。ここまででRailsアプリ、Herokuのadd-onsの準備は完了になりますので、あとはこのアプリをdeployしていくだけです。
4. Rails on DockerをHerokuにDeployする
Rails on DockerのHerokuへのDeploy方法は以下の記事でもまとめています。
Rails on DockerをHerokuでDeployするまで - Qiitaこの記事ではpostgresのadd-ons追加などが完了しているので必要なところだけ書いていきます。
$ heroku container:login $ heroku container:push web $ heroku container:release web $ heroku run rails db:migrateこれでアプリのデプロイが完了するはずなので、あとはサイトを開いてみます。
$ heroku openローカルでテストしてみた時と同じようにファイルをアップロードできるはずです。
また、Cloudinaryのサイトの「Media Library」にその画像ファイルが登録されているのみ見れるはずです。ちなみにActiveStorageはそのモデルが削除されるときに画像ファイルも一緒にdeleteしてくれるのもすごい便利ですね。
あとがき
ということで、Rails on Docker on HerokuでActiveStorage + Cloudinaryの画像管理ができました。
Carrier Waveとかなしで画像扱えるのは便利でした〜。herokuも1コマンドでアドオンが追加できて便利!
- 投稿日:2019-10-02T00:50:56+09:00
[Rails]ローディング機能の実装
はじめに
今回動画を投稿した後など読み込む時間がかかったりして、待つ時間があったのが気になったので以下のようなローディングのアニメーションの実装をしました。
環境
Rails 5.2.3
Ruby 2.5.1実装方法
様々な方法がありますが、私の場合は以下を参考にして
CSS
でアニメーションを作成しました。参考資料
https://recooord.org/loading-animation/
ビューファイル
先ず
application.html.haml
ファイルにローディングアニメーション用のクラスをbody
下に記述します。application.html.haml%body .loader-wrap .loaderSCSSファイル
次にSCSSにローディングアニメーション用のレイアウトを記述します。
色々記述してますが、先程の参考資料の中にあるサイトの内容を殆どコピペするだけで実装出来ます。
後は色や大きさなどを変更したりして自分の好みのレイアウトにして下さい。使用サイト:Single Element CSS Spinners
https://projects.lukehaas.me/css-loaders/
loading.scss.loader-wrap { position: fixed; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; } .loader, .loader:before, .loader:after { border-radius: 50%; } .loader { color: black; font-size: 11px; text-indent: -99999em; margin: 55px auto; position: relative; width: 10em; height: 10em; box-shadow: inset 0 0 0 1em; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); } .loader:before, .loader:after { position: absolute; content: ''; } .loader:before { width: 5.2em; height: 10.2em; background: white; border-radius: 10.2em 0 0 10.2em; top: -0.1em; left: -0.1em; -webkit-transform-origin: 5.2em 5.1em; transform-origin: 5.2em 5.1em; -webkit-animation: load2 2s infinite ease 1.5s; animation: load2 2s infinite ease 1.5s; } .loader:after { width: 5.2em; height: 10.2em; background: white; border-radius: 0 10.2em 10.2em 0; top: -0.1em; left: 5.1em; -webkit-transform-origin: 0px 5.1em; transform-origin: 0px 5.1em; -webkit-animation: load2 2s infinite ease; animation: load2 2s infinite ease; } @-webkit-keyframes load2 { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes load2 { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }後は今回はSCSSを使用している為、
@import
でapplication.scss
にSCSSファイルを読み込むのを忘れないようにします。application.scss@import "loading";jQuery
後はアニメーションの設定をJSファイルに記述するだけです。
使用部分は「ページの読み込みが完了したらアニメーションの非表示の部分」まででも問題ありません。loading.js$(document).on('turbolinks:load', function() { $(function(){ var loader = $('.loader-wrap'); //ページの読み込みが完了したらアニメーションを非表示 $(window).on('load',function(){ loader.fadeOut(); }); //ページの読み込みが完了してなくても2秒後にアニメーションを非表示にする setTimeout(function(){ loader.fadeOut(); },2000); }); });最後に
画像を使用する方法も他にありましたが、私は今回こちらの方で実装しました。
結構簡単に実装出来るので気になった方は試してみて下さい。