- 投稿日:2019-04-15T23:48:20+09:00
model内のインスタンスメソッドの中でインスタンスの属性値を取得する
経緯
- 自分が書いた過去のコード(Ruby書き始めだった頃のもの)を見ていると、「今はとりあえずこのようにしか書けないけど、本当はもっとよりよく書けるはずだ」と思っていた部分が目に入ったので、直します。
- 表題の件について、誰か同じように詰まった方の参考になれればいいのですが。。。
修正前
- 以下のようなコードです。しかしすごい書き方していますね。。。
game.rbdef get_gameset_msg gameset_msg = "試合中" if self[:gameset_flag] gameset_msg = "試合終了" end return gameset_msg end修正後
- カラム名は修正していませんが、「gameset_flag」は「is_gameset」とかの方がいいんでしょうか。。。
game.rbdef get_gameset_msg self.gameset_flag ? "試合終了" : "試合中" endポイント
- 基本的な取得方法(修正後と同じコード)
- model内のインスタンスメソッドの中では、selfでインスタンス本体を指します。
self.xxx
で属性値を取得できます。(こういう書き方って、あんまり載ってない気がするのですが。。。)game.rbdef get_gameset_msg self.gameset_flag ? "試合終了" : "試合中" end
- 属性名を動的に生成する場合
- イニングごとの得点を合計した値が欲しい場合などは、動的にカラム名を生成することでコード量を減らせますが、この場合はハッシュのvalueを取得するように書きます。
self.xxx
のようには書けません。game.rbdef get_sum_top sum_top = 0 9.times {|n| str_top = "top" << (n + 1).to_s sum_top += self[str_top].to_i } sum_top end
- 属性名を動的に生成する場合(その2)
- 上記のコードは、以下のように
send
メソッドを使って書くこともできます。メソッド名を文字列で指定して実行する場合に使えるメソッドです。ただ、今回のような場合は上記のようにself[str_top]
の方が短くていいですかね。game.rbdef get_sum_top sum_top = 0 15.times {|n| str_top = "top" << (n + 1).to_s sum_top += self.send(str_top).to_i } sum_top end参考
- 投稿日:2019-04-15T23:23:06+09:00
rails devise name login
はじめに
deviseでログイン機能を作成するときに名前とパスワードでログイン機能を作成したい方向けに記事を書きます。
基本的にコピペのみで完成します。
コードを理解してください。環境
- macOS mojave
- rbenv 1.1.1
- ruby 2.5.3p105
- Rails 5.2.3
実装
email, passwordで新規登録、ログインする機能の作成
$ rails new devise_name $ cd devise_name $ rails g controller home top after_loginconfig/routes.rbRails.application.routes.draw do root 'home#top' get 'home/after_login' endGemfile...追記 gem 'devise'$ bundle $ rails g devise:install $ rails g devise User $ rails db:migrateapp/views/home/top.html.erb<%= link_to '新規登録', new_user_registration_path %> <%= link_to 'ログイン', new_user_session_path %>app/controllers/application_controller.rbclass ApplicationController < ActionController::Base def after_sign_in_path_for(resource) home_after_login_path end endapp/views/home/after_login.html.erb<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>name, email, passwordで新規登録、name, passwordでログインする機能の作成
- nameカラムの作成 & emailのバリデーション系を全て外す
$ rails g migration AddNameToUsers name:string $ rails g migration ChangeColumnToUsers $ rails g migration remove_index_email_from_usersdb/migrate/日時_change_column_to_users.rbclass ChangeColumnToUsers < ActiveRecord::Migration[5.2] # 変更内容 def up change_column :users, :email, :string, null: true, default: "" end # 変更前の状態 def down change_column :users, :email, :string, null: false, default: "" end enddb/migrate/日時_remove_index_email_from_users.rbclass RemoveIndexEmailFromUsers < ActiveRecord::Migration[5.2] def change remove_index :users, column: :email, unique: true end end$ rails db:migrateconfig/initializers/devise.rb...編集 config.authentication_keys = [:name]app/models/user.rb...追記 def email_required? false end def email_changed? false end
- 新規登録フォーム, ログインフォームの編集
$ rails g devise:viewsapp/views/devise/registrations/new.html.erb...追記 <div class="field"> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "name" %> </div>app/views/devise/sessions/new.html.erb...編集 <div class="field"> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "name" %> </div>
- パラメータの許可
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? def after_sign_in_path_for(resource) home_after_login_path end protected def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :email]) devise_parameter_sanitizer.permit(:sign_in, keys: [:name]) end end以上。
完成コード
- 投稿日:2019-04-15T23:23:06+09:00
[Ruby on Rails] devise name(名前)でログイン
はじめに
deviseでログイン機能を作成するときに名前とパスワードでログイン機能を作成したい方向けに記事を書きます。
基本的にコピペのみで完成します。
コードを理解してください。環境
- macOS mojave
- rbenv 1.1.1
- ruby 2.5.3
- Rails 5.2.3
実装
email, passwordで新規登録、ログインする機能の作成
$ rails new devise_name $ cd devise_name $ rails g controller home top after_loginconfig/routes.rbRails.application.routes.draw do root 'home#top' get 'home/after_login' endGemfile...追記 gem 'devise'$ bundle $ rails g devise:install $ rails g devise User $ rails db:migrateapp/views/home/top.html.erb<%= link_to '新規登録', new_user_registration_path %> <%= link_to 'ログイン', new_user_session_path %>app/controllers/application_controller.rbclass ApplicationController < ActionController::Base def after_sign_in_path_for(resource) home_after_login_path end endapp/views/home/after_login.html.erb<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>name, email, passwordで新規登録、name, passwordでログインする機能の作成
- nameカラムの作成 & emailのバリデーション系を全て外す
$ rails g migration AddNameToUsers name:string $ rails g migration ChangeColumnToUsers $ rails g migration remove_index_email_from_usersdb/migrate/日時_change_column_to_users.rbclass ChangeColumnToUsers < ActiveRecord::Migration[5.2] # 変更内容 def up change_column :users, :email, :string, null: true, default: "" end # 変更前の状態 def down change_column :users, :email, :string, null: false, default: "" end enddb/migrate/日時_remove_index_email_from_users.rbclass RemoveIndexEmailFromUsers < ActiveRecord::Migration[5.2] def change remove_index :users, column: :email, unique: true end end$ rails db:migrateconfig/initializers/devise.rb...編集 config.authentication_keys = [:name]app/models/user.rb...追記 def email_required? false end def email_changed? false end
- 新規登録フォーム, ログインフォームの編集
$ rails g devise:viewsapp/views/devise/registrations/new.html.erb...追記 <div class="field"> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "name" %> </div>app/views/devise/sessions/new.html.erb...編集 <div class="field"> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "name" %> </div>
- パラメータの許可
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? def after_sign_in_path_for(resource) home_after_login_path end protected def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :email]) devise_parameter_sanitizer.permit(:sign_in, keys: [:name]) end end以上。
完成コード
- 投稿日:2019-04-15T22:42:00+09:00
rails aborted! StandardError: An error has occurred, this and all later migrations canceled:
初心者がrails tutorialでscaffoldでUserモデルを生成後、rails db:migrateを入力したときに遭遇したエラー処理について共有します。
mac-no-MacBookPro:toy_app mac$ ./qs rails db:migrate Starting toy_app_db_1 ... done == 20190413154520 CreateUsers: migrating ====================================== -- create_table(:users) rails aborted! StandardError: An error has occurred, this and all later migrations canceled: PG::DuplicateTable: ERROR: relation "users" already exists : CREATE TABLE "users" ("id" bigserial primary key, "name" character varying, "email" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)migrateした後にusers tableが既に存在すると表示されました。
そこで$ rails db:migrate:reset $ rails db:migrateresetのコード入力後、再度migrateを試みるも状況は変わらず。
最終的には下記のようにエディタから直接いじり、解決できました。DBのmigrateファイルの中の今回DBに反映させたかった部分を一度コメントアウト。
class CreateMicroposts < ActiveRecord::Migration[5.2] def change #create_table :microposts do |t| #t.text :content #t.integer :user_id #t.timestamps #end end endその後
$ rails db:migrateそして、この後はコメントアウトした「#」の文字を消します。
class CreateMicroposts < ActiveRecord::Migration[5.2] def change create_table :microposts do |t| t.text :content t.integer :user_id t.timestamps end end endそして最後に以下のコードを打ち込み、解決しました。
$ rails db:migrate:down VERSION= <該当のmigrateファイル名> $ rails db:migrate
- 投稿日:2019-04-15T22:01:11+09:00
「heroku run」で発生するETIMEDOUTの原因と解決方法について
Macのローカル環境でRailsチュートリアルを進めていると,Herokuでマイグレーションが失敗してしまい,次のエラーが発生してしまいました。
〔ターミナル〕 $ heroku run rails db:migrate ▸ETIMEDOUT: connect ETIMEDOUT 50.19.103.36:5000 〔Herokuログ抜粋〕 Error R13 (Attach error) -> Failed to attach to process解決方法は
「heroku run:detached」
を使用することであり,原因も「5000番ポートが使えない」ということであることが,調べると簡単に出てくると思います。ただ,「何故使えないのか」という背景が日本語で中々見つからず,このコマンドを使用することの不安感の高まりから,英語に向き合って調べたら安心を得るに至りましたので,同じ不安を抱えている方の参考になれば幸いです。
<原因>
初めに
「heroku run」
の仕組みは,クライアントの5000番ポートでHerokuに接続することにより,クライアント側のコンソールに対してコマンドの入出力を実行可能にするものである。しかし,クライアント側において,ファイアウォール等のローカルネットワークに原因があり,Herokuからクライアントのコンソールに接続できない場合は,当該エラーが発生する。
<解決方法>
「heroku run:detached」
を使用することにより,コマンドがバックグラウンドで実行されることから,Herokuからの標準出力を受け取らないことで。5000番ポートに接続される必要がなくなるため,本問題が解決される。ただし,クライアント側のコンソールに実行結果が出力されなくなることから,正常に実行されたか表示されないため,
「heroku logs」
によりログ情報を確認する必要がある。〔参考入力結果〕 $ heroku run:detached rails db:migrate >Running rails db:migrate on ⬢ [Heroku登録のアプリ名]... done, run.5930 (Free) >Run heroku logs --app [Heroku登録のアプリ名] --dyno run.5930 to view the output. $ heroku logs --app [Heroku登録のアプリ名] --dyno run.5930 >・ >・ #「heroku run:detached rails db:migrate」実行結果のログが表示される >・<結論>
「run:detached」
を使用しても,アプリの本番環境等に影響は無いでしょう。
注意事項として,ローカルのコンソール上で実行結果が出力されないことにより,失敗時にエラーを見落とす可能性が残りますので,使用後は必ずHerokuのログで実行結果を確認しましょう。ただ,この解決方法では,根本の原因を解決しないことになり
「heroku logs」
の追加作業が発生し,解決するには「5000番ポート」の解放か,ファイアウォールの設定か,又はHeroku側の問題なのか…次の原因のための追加調査をする必要があります。
しかし,追加作業と追加調査の作業労力を比較すると,私の現在の知識では「run:detached」
を使用する方が費用対効果が高いため,ここで調査を終了します。
今後,技術知識が増えたら適宜更新したいと思います。※追伸
私の英語力及び技術知識不足による言葉の誤用の可能性も考えられますので,記載内容に誤りがありましたら,ご指摘いただけると大変嬉しいです。<参考情報>
○失敗したログ情報
〔コンソールの実行結果〕 $ heroku run rails db:migrate ▸ETIMEDOUT: connect ETIMEDOUT 50.19.103.36:5000 $ heroku run bash ▸ETIMEDOUT: connect ETIMEDOUT 50.19.103.36:5000 $ heroku run console ▸ETIMEDOUT: connect ETIMEDOUT 50.19.103.36:5000〔Herokuログ(コマンドに対応したログ情報に加工)〕 $ heroku run rails db:migrate : Awaiting client : State changed from starting to up : State changed from up to complete : Error R13 (Attach error) -> Failed to attach to process : Process exited with status 128 $ heroku run bash : Awaiting client : State changed from starting to up : State changed from up to complete : Error R13 (Attach error) -> Failed to attach to process : Process exited with status 128 $ heroku run console : State changed from starting to up : Awaiting client : State changed from up to complete : Error R13 (Attach error) -> Failed to attach to process : Process exited with status 128○参考サイト
・Heroku公式サイト1:R13 - Attach error
「heroku run」
で開始されたDynoが,呼び出し側のクライアントに接続できなかった。・Heroku公式サイト2:Timeout awaiting process
「heroku run」
は5000番ポートで接続するが,ローカルネットワーク等の理由で接続できない場合は,エラーが発生する。
telnetを使用して5000番ポートで接続することにより,Herokuへの接続をテストできるが,出力が得られない場合,クライアント側でHerokuへのアクセスをブロックしている。
この問題を解決するには,IT部門,ISP,又はファイアウォールの製造元に連絡することをお勧めする。・Heroku公式サイト3:Running tasks in background
「heroku run:detached」
を使用することによりバックグラウンドでDynoを実行可能である。「heroku run」
とは異なり,これらのdynosはクライアント側に出力する代わりにHeroku側のログに出力を送る。これらのコマンドからの出力を表示するには,「heroku logs」
を使用する必要がある。・Stack Overflow:Heroku rake db:migrate results in Error R13 (Attach error) -> Failed to attach to process
※内容は,概ね公式サイト通りです。
- 投稿日:2019-04-15T20:28:25+09:00
RailsプロジェクトへのVue.js導入
Rails × Vueのセットアップ
導入方法は以下の4つが考えられそうだが今回は1.で導入
- デフォルトのRailsプロジェクトの中にVue.jsを導入
- APIモードのRailsプロジェクトの中にVue.jsを導入
- RailsコンテナとVueのコンテナに分けてコンテナ同士で接続
- Rails用サーバーとVue用のサーバーでそれぞれ構築して、エンドポイントで接続
Gemfilegem "webpacker"# gemのインストール bundle install # webpackerインストール bin/rails webpacker:install # コンパイル bin/webpack # vueインストール bin/rails webpacker:install:vue # Top作成 rails g controller Home index --no-assets --no-helper --no-test-framework # vue読み込み sed -ie '10i \ <%= javascript_pack_tag "hello_vue" %>' app/views/layouts/application.html.erb
- localhostにアクセスしてhello worldを確認
雑感
何も開発していないのに最初から色々1つのプロジェクトにたくさん入っちゃっている感
- 投稿日:2019-04-15T20:28:01+09:00
Rails6 のちょい足しな新機能を試す3(rails server -u編)
はじめに
Rails 6 に追加されそうな新機能を試す第3段。
rails server
の-u
オプション機能です。
記載時点では、Rails は 6.0.0.beta3 です。gem install rails --prerelease
でインストールできます。$ rails --version Rails 6.0.0.beta3u``単純なCRUD機能をscaffold で作る
新機能を試すために、scaffold で単純なCRUD機能を作ってみます。
$ rails new sandbox_6_0_0b3 $ cd sandbox_6_0_0b3 $ rails g scaffold User name従来の機能
rails server のオプションを調べてみます。
$ rails s --help Usage: rails server [puma, thin etc] [options] Options: -p, [--port=port] # Runs Rails on the specified port - defaults to 3000. -b, [--binding=IP] # Binds Rails to the specified IP - defaults to 'localhost' in development and '0.0.0.0' in other environments'. -c, [--config=file] # Uses a custom rackup configuration. # Default: config.ru -d, [--daemon], [--no-daemon] # Runs server as a Daemon. -e, [--environment=name] # Specifies the environment to run this server under (development/test/production). -P, [--pid=PID] # Specifies the PID file. # Default: tmp/pids/server.pid -C, [--dev-caching], [--no-dev-caching] # Specifies whether to perform caching in development. [--early-hints], [--no-early-hints] # Enables HTTP/2 early hints.
-u
オプションはありません。新機能
Rails 6.0.0beta3 で試してみます。
$ rails s --help Usage: rails server [thin/puma/webrick] [options] Options: -p, [--port=port] # Runs Rails on the specified port - defaults to 3000. -b, [--binding=IP] # Binds Rails to the specified IP - defaults to 'localhost' in development and '0.0.0.0' in other environments'. -c, [--config=file] # Uses a custom rackup configuration. # Default: config.ru -d, [--daemon], [--no-daemon] # Runs server as a Daemon. -e, [--environment=name] # Specifies the environment to run this server under (development/test/production). -u, [--using=name] # Specifies the Rack server used to run the application (thin/puma/webrick). -P, [--pid=PID] # Specifies the PID file. # Default: tmp/pids/server.pid -C, [--dev-caching], [--no-dev-caching] # Specifies whether to perform caching in development. [--early-hints], [--no-early-hints] # Enables HTTP/2 early hints. [--log-to-stdout], [--no-log-to-stdout] # Whether to log to stdout. Enabled by default in development when not daemonized.
-u
オプションで rack サーバーを指定するようになってます。では、試してみましょう。
$ rails s -u puma => Booting Puma => Rails 6.0.0.beta3 application starting in development => Run `rails server --help` for more startup options Puma starting in single mode... * Version 3.12.1 (ruby 2.6.2-p47), codename: Llamas in Pajamas * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://localhost:3000 Use Ctrl-C to stopwebrickも試してみます。
$ rails s -u webrick => Booting WEBrick => Rails 6.0.0.beta3 application starting in development http://localhost:3000 => Run `rails server --help` for more startup options [2019-04-15 10:47:39] INFO WEBrick 1.4.2 [2019-04-15 10:47:39] INFO ruby 2.6.2 (2019-03-13) [x86_64-linux-musl] [2019-04-15 10:47:39] INFO WEBrick::HTTPServer#start: pid=977 port=3000せっかくなので、
thin
とfalcon
も試してみます。 Gemfile にthin
とfalcon
を追加します。Gemfilegem 'thin' gem 'falcon'
bundle install
を実行した後、thin
を試してみます。$ rails s -u thin => Booting Thin => Rails 6.0.0.beta3 application starting in development http://localhost:3000 => Run `rails server --help` for more startup options Thin web server (v1.7.2 codename Bachmanity) Maximum connections set to 1024 Listening on localhost:3000, CTRL+C to stop最後は
falcon
です。$ rails s -u falcon -b 0.0.0.0 => Booting Falcon => Rails 6.0.0.beta3 application starting in development http://0.0.0.0:3000 => Run `rails server --help` for more startup options
falcon
は-b
オプションを指定しないとエラーになりました。 falcon もそのまま使えるとわかったのは収穫でした。参考情報
- 投稿日:2019-04-15T20:05:58+09:00
【Rails】オラ自作のブックマークシェアWebアプリで『作業が捗るおやつ・ドリンク集』を紹介すっぞ!
オッス(Z戦士)
突然ですが、作業中の"おやつ"と"飲み物"って生きてく上での酸素と同じくらい大切だと思うんですよね。
ぼくは大量のコードと長時間向き合ってもビクともしない超(スーパー)エンジニア人ではないので、
作業中は仙豆に相当する"おやつ"と"飲み物"で都度回復しないと、「hassoubeat(ぼく)は置いてきた...ハッキリ言ってこれからの業務にはついていけない...」
といった具合に、天さん(上司)に見捨てられること請け合いです。
そんなぼくをギリギリ戦いに参加できるヤムチャレベルまで引き上げてくれるドーピングアイテム。それが、作業中の"おやつ"と"飲み物"なのです。
今回はそんなぼくが愛好する"おやつ"、"飲み物"を...
オラが作ったRailsのWebアプリで『作業が捗るおやつ・ドリンク集』をいっちょ紹介してみっか!!!(唐突)
作業が捗るおやつ・ドリンク集 by hassoubeat LinkS
赤枠の箇所をクリック・タッチしてもらえればブックマークに対して一言コメントが読めるゾ個人的に"きかんしゃトーマスとなかまたちチューイングキャンディ」と「マテ茶」は実力はあるのに、あまり知られていないのが残念で仕方ないです。
もし興味を持っていただけたら、リンク先からポチってお試しいただけると嬉しいです。
...。
Webアプリ側にコメントを書いているので当たり前なのですが、おやつに関して書くことがなくなってしまいました。このまま終わるのも寂しいという皆様のためにぃ(ねっとり)
ここから先は今回開発したWebアプリの話でもしようかと思います。
(おやつの話以外)興味ないね(魔晄中毒者)という方は、
オススメの"おやつ"と"飲み物"をコメントに書いてからブラウザバックしてもらえたら嬉しいゾ自作Webアプリの紹介
今回開発したWebアプリ『LinkS(リンクス)』の紹介にイクゾー!
そもそもこのアプリはなんなの?
コメントを付けたブックマーク集をワンクリックで公開してSNSにも簡単に共有できるブックマークシェアWebアプリです。
実際にシェアするまでの流れを見てもらいましょう。
1.フォルダー作成
ブックマークの公開・共有はフォルダー単位で行われるため、まずフォルダーを。
公開に設定しない限り、自分だけのブックマーク集としても利用できます。2.ブックマーク登録
さっき作ったフォルダーにブックマークを登録します。Just Monika.3.フォルダー公開
フォルダーの公開設定を公開に変更することで、ログインしている本人以外にもURLを叩けばそのフォルダーが見れるように。4.シェア
おすすめゲームのPV集 by hassoubeat LinkS
URLを直接シェアする以外にも、LinkSからSNSに直接シェアすることもできます。ちなみにスマホでもちゃんと使えます
...。
機能がシンプル過ぎるので、話すことがなくなりました。
一応申し訳程度にいいね機能、管理機能とかも実装してます。現在β版ですが、もし気になる人がいたら捨てアドでアカウント登録して使ってみてくれたら嬉しいゾ。
なんで作ろうと思い立ったワケ?
理由は2つありますねぇ!
1.RubyOnRailsのポートフォリオを作りたかった
2.弟がHTMLの勉強を始めるにあたって何をしたらいいか聞いてきた1.RubyOnRailsのポートフォリオを作りたかった
Webアプリケーション開発のフレームワークとしての知名度が高いRubyOnRailsの学習の成果として、
何かポートフォリオ作りてぇな...。と考えていたのですが、なかなかピンとくる題材がなく...。
(あんまり手の混んだやつは作るのがめんでぇぞ!の意)2.弟がHTMLの勉強を始めるにあたって何をしたらいいか聞いてきた
ある日弟が「HTMLの勉強をしたいのだが、まず何から手を付けたらよいのか?」と聞いてきました。
入門者向けのテキスト読んでもいいし、活字が苦手なやつだしドットインストールみたいなサイトで動画で動きを見ながらやったほうがいいかな...。
みたいなことを考えてHTML初学者が手を付けるべきサイトやテキストのAmazonのリンクに補足のコメントを付けてまとめていました。こんな感じの一言コメントを付けたリンク集を簡単に共有できるWebアプリとかねーかな...
そんな感じのコメント付きのリンク集を簡単にシェアできるWebアプリ...。
Railsのポートフォリオの題材としてちょうどいい...!という渡りに船な出来事があって、LinkSは誕生しました。(ガイドのお姉さん風)
これいる?
Q.(ブラウザがブックマークをクラウド管理してくれるこのご時世に)これいる?
文字制限があるTwitterで自分のオススメ〇〇集!みたいなのを共有したい人に需要があるかもしれない(希望的観測)
Q.(似たようなサービスがあるのに)これいる?
A.
(作ったのは)おれじゃない
(超エンジニア人の)あいつらがつくった
(おれはそんなサービス)しらない
(実装が)すんだこと
既に似たようなサービスがあることを気にしていたらポートフォリオなんて作れないんだよぉぉぉぉ!
開発中しょうもないミスで一時間くらい詰まっていた時、心の中で叫ぶセリフ第一位。使ったフレームワーク
RubyOnRails
説明不要のWebアプリケーションフレームワーク。
いずれRubyの仕事もしたいなーってことで勉強を始めたけど、ほんとに生産性上がってMAX大草原。
あんまりによかったのでRailsを参考にしているらしいPHPのLaravelも近々触ってみようかと思った(小並感)Haml
テンプレートエンジン。
Haml か Slimがよく採用されているらしいけど、なんとなくHamlを採用。
はじめは「書きにくいな...全部ERBで書いた後にerb2hamlでhamlに変換してやろうか...くそったれぇ...!(本末転倒)」なんてその気になっていたお前の姿はお笑いだったぜ。
慣れれば慣れるほどコードの見通しが良くなって、結果的に生産性向上に大きく貢献してくれました。Bootstrap
説明不要のCSSフレームワーク。
デザイン面がクソザコナメクジ過ぎていっつもこればっかり使っているので、今度違うWebアプリ作る時は頼らないで作りたい(猛省)jQuery
い つ も の (JavaScriptフレームワーク)
「まだオワコンフレームワーク使ってんのかよ?」と思った貴方。
いきなりvue.jsかよ。モダンッパリらしいな。世界最高フレームワークjQueryを侮辱した罪...軽くねーぜ?
ごめんなさい。慣れてるからっていっつもなんとなくで使っちゃうんです...。
jQueryからvue.jsのステップアップ記事とか見てると、凄い良さそうなんで今度使います...。
(すぐ使うとは言ってない)改修、機能追加したい部分
1. ブックマークのURL入力時に自動でページタイトルをスクレイピングして、タイトルの入力の手間軽減
クロスドメインでのスクレイピングを跨げるライブラリが利用しているYahoo!のYQLが完全に死んだらしく、
どうにかして実現できないかなと模索中。2. GoogleChromeの拡張機能で、ブラウザのブックマークからのインポート処理機能
そもそも普段使ってるブラウザのブックマークからインポートできたら一番ラクだよねってこと。
GoogleChrome拡張機能開発の勉強をやってみたいので、割とモチベ高し。3. SPA化
RailsをAPIモードにして、ページ表示はクライアントからAPIを叩くだけの構成を実装してみたい。
このアプリでは作り直すのがめんどくさいので多分やらない(屑)(ポートフォリオ作成を)完走した感想
まずRubyOnRailsの生産性の高さに驚きました。
使わなくても分かるシンプル構成のシステムなのもあり、ほとんどサーバ側のコードは書いてないです。
全体工数の7割はクライアント側のUI作成に時間が取られてます。...。
これもうRubyOnRailsのポートフォリオとして成立してるかわかんねぇな(屑)でもやっぱり設計、製造、テスト、リリース : 俺は気軽に色々やれて楽しいですね。
実務だとなかなかそうはいかないので、みんなも気軽にポートフォリオ作成して...見せ合いっこしよっ!!!
俺もやったんだからさ(同調圧力)あっ(唐突)、作業中に良さげな"おやつ"と"飲み物"があったら、コメント欄で教えてください。
LinkSで教えてくれたらもっと嬉しいです余談:他のおすすめリンク集
せっかく作ったアプリなので、他のぼくセレクトも公開します。
RubyOnRailsの学習に役立ったリンク集 by hassoubeat LinkS
RubyOnRailsの学習を始めるにあたって参考になったリンク集です。
おすすめゲームのPV集 by hassoubeat LinkS
ハードウェア問わずおすすめのゲーム集です。
落ち込んでいる時に元気が出る動画集 by hassoubeat LinkS
落ち込んでいる時に見ると元気を貰える動画集です。
※ ぼくセレクトなので、効果の保証はできません
- 投稿日:2019-04-15T20:05:58+09:00
【Rails】【ポートフォリオ】自作のブックマークシェアWebアプリで『作業が捗るおやつ・ドリンク集』を紹介します
オッス(Z戦士)
突然ですが、作業中の"おやつ"と"飲み物"って生きてく上での酸素と同じくらい大切だと思うんですよね。
ぼくは大量のコードと長時間向き合ってもビクともしない超(スーパー)エンジニア人ではないので、
作業中は仙豆に相当する"おやつ"と"飲み物"で都度回復しないと、「hassoubeat(ぼく)は置いてきた...ハッキリ言ってこれからの業務にはついていけない...」
といった具合に、天さん(上司)に見捨てられること請け合いです。
そんなぼくをギリギリ戦いに参加できるヤムチャレベルまで引き上げてくれるドーピングアイテム。それが、作業中の"おやつ"と"飲み物"なのです。
今回はそんなぼくが愛好する"おやつ"、"飲み物"を...
オラが作ったRailsのWebアプリで『作業が捗るおやつ・ドリンク集』をいっちょ紹介してみっか!!!(唐突)
作業が捗るおやつ・ドリンク集 by hassoubeat LinkS
赤枠の箇所をクリック・タッチしてもらえればブックマークに対して一言コメントが読めるゾ個人的に"きかんしゃトーマスとなかまたちチューイングキャンディ」と「マテ茶」は実力はあるのに、あまり知られていないのが残念で仕方ないです。
もし興味を持っていただけたら、リンク先からポチってお試しいただけると嬉しいです。
...。
Webアプリ側にコメントを書いているので当たり前なのですが、おやつに関して書くことがなくなってしまいました。このまま終わるのも寂しいという皆様のためにぃ(ねっとり)
ここから先は今回開発したWebアプリの話でもしようかと思います。
(おやつの話以外)興味ないね(魔晄中毒者)という方は、
オススメの"おやつ"と"飲み物"をコメントに書いてからブラウザバックしてもらえたら嬉しいゾ自作Webアプリの紹介
今回開発したWebアプリ『LinkS(リンクス)』の紹介にイクゾー!
そもそもこのアプリはなんなの?
コメントを付けたブックマーク集をワンクリックで公開してSNSにも簡単に共有できるブックマークシェアWebアプリです。
実際にシェアするまでの流れを見てもらいましょう。
1.フォルダー作成
ブックマークの公開・共有はフォルダー単位で行われるため、まずフォルダーを。
公開に設定しない限り、自分だけのブックマーク集としても利用できます。2.ブックマーク登録
さっき作ったフォルダーにブックマークを登録します。Just Monika.3.フォルダー公開
フォルダーの公開設定を公開に変更することで、ログインしている本人以外にもURLを叩けばそのフォルダーが見れるように。4.シェア
おすすめゲームのPV集 by hassoubeat LinkS
URLを直接シェアする以外にも、LinkSからSNSに直接シェアすることもできます。ちなみにスマホでもちゃんと使えます
...。
機能がシンプル過ぎるので、話すことがなくなりました。
一応申し訳程度にいいね機能、管理機能とかも実装してます。現在β版ですが、もし気になる人がいたら捨てアドでアカウント登録して使ってみてくれたら嬉しいゾ。
なんで作ろうと思い立ったワケ?
理由は2つありますねぇ!
1.RubyOnRailsのポートフォリオを作りたかった
2.弟がHTMLの勉強を始めるにあたって何をしたらいいか聞いてきた1.RubyOnRailsのポートフォリオを作りたかった
Webアプリケーション開発のフレームワークとしての知名度が高いRubyOnRailsの学習の成果として、
何かポートフォリオ作りてぇな...。と考えていたのですが、なかなかピンとくる題材がなく...。
(あんまり手の混んだやつは作るのがめんでぇぞ!の意)2.弟がHTMLの勉強を始めるにあたって何をしたらいいか聞いてきた
ある日弟が「HTMLの勉強をしたいのだが、まず何から手を付けたらよいのか?」と聞いてきました。
入門者向けのテキスト読んでもいいし、活字が苦手なやつだしドットインストールみたいなサイトで動画で動きを見ながらやったほうがいいかな...。
みたいなことを考えてHTML初学者が手を付けるべきサイトやテキストのAmazonのリンクに補足のコメントを付けてまとめていました。こんな感じの一言コメントを付けたリンク集を簡単に共有できるWebアプリとかねーかな...
そんな感じのコメント付きのリンク集を簡単にシェアできるWebアプリ...。
Railsのポートフォリオの題材としてちょうどいい...!という渡りに船な出来事があって、LinkSは誕生しました。(ガイドのお姉さん風)
これいる?
Q.(ブラウザがブックマークをクラウド管理してくれるこのご時世に)これいる?
文字制限があるTwitterで自分のオススメ〇〇集!みたいなのを共有したい人に需要があるかもしれない(希望的観測)
Q.(似たようなサービスがあるのに)これいる?
A.
(作ったのは)おれじゃない
(超エンジニア人の)あいつらがつくった
(おれはそんなサービス)しらない
(実装が)すんだこと
既に似たようなサービスがあることを気にしていたらポートフォリオなんて作れないんだよぉぉぉぉ!
開発中しょうもないミスで一時間くらい詰まっていた時、心の中で叫ぶセリフ第一位。使ったフレームワーク
RubyOnRails
説明不要のWebアプリケーションフレームワーク。
いずれRubyの仕事もしたいなーってことで勉強を始めたけど、ほんとに生産性上がってMAX大草原。
あんまりによかったのでRailsを参考にしているらしいPHPのLaravelも近々触ってみようかと思った(小並感)Haml
テンプレートエンジン。
Haml か Slimがよく採用されているらしいけど、なんとなくHamlを採用。
はじめは「書きにくいな...全部ERBで書いた後にerb2hamlでhamlに変換してやろうか...くそったれぇ...!(本末転倒)」なんてその気になっていたお前の姿はお笑いだったぜ。
慣れれば慣れるほどコードの見通しが良くなって、結果的に生産性向上に大きく貢献してくれました。Bootstrap
説明不要のCSSフレームワーク。
デザイン面がクソザコナメクジ過ぎていっつもこればっかり使っているので、今度違うWebアプリ作る時は頼らないで作りたい(猛省)jQuery
い つ も の (JavaScriptフレームワーク)
「まだオワコンフレームワーク使ってんのかよ?」と思った貴方。
いきなりvue.jsかよ。モダンッパリらしいな。世界最高フレームワークjQueryを侮辱した罪...軽くねーぜ?
ごめんなさい。慣れてるからっていっつもなんとなくで使っちゃうんです...。
jQueryからvue.jsのステップアップ記事とか見てると、凄い良さそうなんで今度使います...。
(すぐ使うとは言ってない)改修、機能追加したい部分
1. ブックマークのURL入力時に自動でページタイトルをスクレイピングして、タイトルの入力の手間軽減
クロスドメインでのスクレイピングを跨げるライブラリが利用しているYahoo!のYQLが完全に死んだらしく、
どうにかして実現できないかなと模索中。2. GoogleChromeの拡張機能で、ブラウザのブックマークからのインポート処理機能
そもそも普段使ってるブラウザのブックマークからインポートできたら一番ラクだよねってこと。
GoogleChrome拡張機能開発の勉強をやってみたいので、割とモチベ高し。3. SPA化
RailsをAPIモードにして、ページ表示はクライアントからAPIを叩くだけの構成を実装してみたい。
このアプリでは作り直すのがめんどくさいので多分やらない(屑)(ポートフォリオ作成を)完走した感想
まずRubyOnRailsの生産性の高さに驚きました。
使わなくても分かるシンプル構成のシステムなのもあり、ほとんどサーバ側のコードは書いてないです。
全体工数の7割はクライアント側のUI作成に時間が取られてます。...。
これもうRubyOnRailsのポートフォリオとして成立してるかわかんねぇな(屑)でもやっぱり設計、製造、テスト、リリース : 俺は気軽に色々やれて楽しいですね。
実務だとなかなかそうはいかないので、みんなも気軽にポートフォリオ作成して...見せ合いっこしよっ!!!
俺もやったんだからさ(同調圧力)あっ(唐突)、作業中に良さげな"おやつ"と"飲み物"があったら、コメント欄で教えてください。
LinkSで教えてくれたらもっと嬉しいです余談:他のおすすめリンク集
せっかく作ったアプリなので、他のぼくセレクトも公開します。
RubyOnRailsの学習に役立ったリンク集 by hassoubeat LinkS
RubyOnRailsの学習を始めるにあたって参考になったリンク集です。
おすすめゲームのPV集 by hassoubeat LinkS
ハードウェア問わずおすすめのゲーム集です。
落ち込んでいる時に元気が出る動画集 by hassoubeat LinkS
落ち込んでいる時に見ると元気を貰える動画集です。
※ ぼくセレクトなので、効果の保証はできません
- 投稿日:2019-04-15T18:45:44+09:00
【Rails】 flash時にメッセージにリンクを埋め込む
- 投稿日:2019-04-15T17:22:43+09:00
Railsのエラーが何なのか辿り着くまでの思考プロセス
●●のエラーだなこれ・・・と正しい推測まで到達するために・・・
undefined hogehoge_methodまずこんな感じでRailsサーバーと立ち上げても長いエラーが出るばかりで、画面が出てこない状況になります。
ここからバトルスタートですね。やりたいこと
エラーがなんなのかを特定する。例えば、DBなのか、リダイレクト関係なのか、ルーティングミスなのかなどのタイポとかと比べて、根の深そうなエラー周りなのかどうかを先ず知りたい
手順
1. こけているメソッドのインスタンスを見てみる
メソッドに問題がない場合、そのさらに先で定義されているかコールされているものがこけているので、そのインスタンスが宣言されているファイルを探しに行きます。2.ファイルを探す
$ find ./探したいディレクトリ -type f -print | xargs grep '検索文字列'findコマンドでファイルを特定し、xargsコマンドに渡して検索文字列がヒットしたファイルを弾きだします。
ここでページが多く作成されていたりすると、あちこちで同名インスタンスが呼ばれているので分からなくなりそうですが、表示できていないページがどこに当たるのかと、ファイルの命名規則が合致していれば、探しやすいはずです。ここで、、viewの名前が分かり易いもの、(Restfullに作られていると、このファイル探査がしやすいですね。)そうやってネストしているメソッドを伝っていくと、最終的に落ちているメソッドがなんなのか理解できる。
後は、そこを修正するだけ。
- 投稿日:2019-04-15T14:59:10+09:00
Rails version update 覚書 その3
前回 https://qiita.com/takakuda/items/f7ea279778971b71cd9b
依存関係のあるgemを一通りupdateし終えたらrails自体のupdateをする
rails update
Gemfileを編集する
- gem "rails", "5.1.~" + gem "rails", "5.2.~"
--conservative
optionを使って依存関係のあるgemのupdateを行わないようにするbundle update --conservative railsその1 https://qiita.com/takakuda/items/895bd6e776e8e7ec08bf
こちらの手順を実行していく。
依存関係のあるgemの更新が終了していればbundle update
自体は成功するはず
bundle update
が成功したらちゃんとrailsが起動できるかを確認していくたぶん起動しないので起動しない原因を調査し、1つずつ修正していく
今回は実際に自分がupdateしたときに発生した修正箇所もろもろ
ArgumentError: Passing string to be evaluated in :if and :unless conditional options is not supported. Pass a symbol for an instance method, or a lambda, proc or block, instead.
:if, :unless を使っている時にstringがサポートされなくなりました
☓ if: 'first_name.blank?' ○ if: proc { |s| s.first_name.blank? }error messageに書いてある通りに対応すれば大丈夫です
undefined method halt_callback_chains_on_return_false= for ActiveSupport:Module (NoMethodError)
halt_callback_chains_on_return_falseはRails 4との後方互換のためのメソッド。
5.2よりhalt_callback_chains_on_return_falseは削除されたため、config/initializers/new_framework_defaults.rb
の中のhalt_callback_chains_on_return_falseの行をコメントアウトすればおっけー。
- 投稿日:2019-04-15T14:31:55+09:00
where後に配列に入っている値をハッシュ形式にする方法。(レコード1件のみ時)
whereで値を取得した後は配列に入っています。
下記のコードですが、Entryモデル中の1つのroom_idには送信者、受信者のuser_idがある。
(1つのroom_idにつき最小、最大2名のみ)
したがって自分以外のuser_idを残すためにwhere.notで自分のuser_idを取得しないようにしている。@room_idには1つのuser_idしかないのがわかっている中で、
each文での取り出しはスマートではない。コード
28: @room_id = Entry.where(room_id: params[:id]).where.not(user_id: current_user.id) 29: @room_id.each do |user| 30: @reception_user = User.find(user.user_id) => 31: binding.pry 32: end 33: link "#{@reception_user.name}さんとのチャットルーム", user_room_path@room_idに入っている値です。
> @room_id => [#<Entry:0x00007ff76be33a40 id: 2, user_id: 2, room_id: 1,試したこと
配列からハッシュにするto_hメソッドを見つけて試したが、無理な様子。
@room_id = Entry.where(room_id: params[:id]).where.not(user_id: current_user.id) @room = @room_id.to_hエラー内容
wrong element type Entry (expected array)解決法
レコードが1件しかないのがわかっているので、firstで配列を展開から展開されハッシュ形式で@entryに渡っている。
@room_id = Entry.where(room_id: params[:id]).where.not(user_id: current_user.id).first
- 投稿日:2019-04-15T14:01:55+09:00
case文での条件分岐方法
滞在しているページごとにサイドバーに表示させるリストの内容を変更したかったので
if文を使い行っていたが、条件が多くなるに連れて可読性が悪くなってきたため、
case文でコードを書き直したが条件分岐が行われなかった。if文でviewに書いたコード
- if params[:controller] == 'users' && params[:action] == 'show'case文を使い書き直したコード
- case params[:controller] - when 'users' && params[:action] == 'show'teratailで質問し解決したのでメモ。
https://teratail.com/questions/184492
下記のようにすることでコントローラーのアクションごとに異なるviewの切り替えを実現できた。- case params.values_at :controller, :action - when ['rooms', 'show']
- 投稿日:2019-04-15T12:33:21+09:00
delayed_job再起動手順
ローカル開発環境でdelayed_jobを利用してメール送信などの実装をしている場合、delayed_jobが起動していないせいでメールが確認できないということがある。
そのような場合はdelayed_jobを再起動してあげる必要がある。### delayed_jobの再起動 $ bin/delayed_job restartなお、キューがたくさん溜まっているとdelayed_jobを再起動したタイミングで一気にメールが飛ぶので、全部削除しておくとよい
$ bundle exec rails c ### 現在溜まっているジョブ数の確認 pry(main)> Delayed::Job.count ### キューの削除 pry(main)> Delayed::Job.delete_all
- 投稿日:2019-04-15T12:24:51+09:00
Payjpに登録したクレジットカードで商品購入を実装する(Rails)
この記事を読む前に
↓前回の投稿内容が実施されていることを前提に記載しています。
Payjpでクレジットカード登録と削除機能を実装する(Rails)実装する機能と前提条件
Payjp(Pay.jp)から既に顧客IDとカードIDを取得済みでの購入を想定しています。
実装するものとしては下記のとおりです。
- 自作のカード登録フォーム(前回)
- カード情報とユーザーの紐づけ(前回)
- ユーザーとカードの登録と削除(前回)
- 商品の購入(←今回)
バージョン情報
ruby 2.3.1
Rails 5.0.7前提条件
- deviseが導入済みでログインができている(current_userを使うため)
- hamlでの記載(gem 'haml-rails')
- payjpのアカウントが既に取得できていて、ユーザーとカードの登録が完了している(前回実施)
- cardテーブルに以下の情報が登録されている(前回実施)
- user_id → UserテーブルのID
- customer_id → payjpの顧客ID
- card_id → payjpのデフォルトカードID
顧客IDとデフォルトカードIDは以下の画面で顧客ごとに確認できます。
もしDBを作成していなかったり可動しなかったりする場合はID直打ちでトライしてみましょう。
顧客詳細確認画面
1.コントローラーを作成しよう
app/controllers/purchase_controller.rbclass PurchaseController < ApplicationController require 'payjp' def index card = Card.where(user_id: current_user.id).first #Cardテーブルは前回記事で作成、テーブルからpayjpの顧客IDを検索 if card.blank? #登録された情報がない場合にカード登録画面に移動 redirect_to controller: "card", action: "new" else Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] #保管した顧客IDでpayjpから情報取得 customer = Payjp::Customer.retrieve(card.customer_id) #保管したカードIDでpayjpから情報取得、カード情報表示のためインスタンス変数に代入 @default_card_information = customer.cards.retrieve(card.card_id) end end def pay card = Card.where(user_id: current_user.id).first Payjp.api_key = ENV['PAYJP_PRIVATE_KEY'] Payjp::Charge.create( :amount => 13500, #支払金額を入力(itemテーブル等に紐づけても良い) :customer => card.customer_id, #顧客ID :currency => 'jpy', #日本円 ) redirect_to action: 'done' #完了画面に移動 end end2.購入画面と完了画面を作成しよう
購入画面
app/views/purchase/index.html.haml%h2 購入を確定しますか? %p Apple MacBook Pro 13インチ %p ¥135,000(送料込み) %br %h3 支払い方法 - if @default_card_information.blank? %br / - else -#以下カード情報を表示 = "**** **** **** " + @default_card_information.last4 - exp_month = @default_card_information.exp_month.to_s - exp_year = @default_card_information.exp_year.to_s.slice(2,3) = exp_month + " / " + exp_year %br = form_tag(action: :pay, method: :post) do %button 購入する
ちなみにexp_monthはカードの期限月、exp_yearは期限年、last4はカードの下4桁を取得します。
https://pay.jp/docs/api/#顧客のカード情報を取得完了画面
app/views/purchase/done.html.haml%h2 購入が完了しました! %p Apple MacBook Pro 13インチ %p ¥135,000(送料込み)3.ルートを設定しよう
config/routes.rb#今回設定分 get 'purchase', to: 'purchase#index' post 'purchase/pay', to: 'purchase#pay' get 'purchase/done', to: 'purchase#done'本当に購入されているのだろうか…
実装はこれで完了です!
画面変遷はできてても登録ができているか不安な場合は
売上一覧の画面で確認できます!
参考
- 投稿日:2019-04-15T10:07:21+09:00
Railsの勉強を初めて、基本的な内容をメモ
はじめに
rails tutorialを終えて、整理するためにアウトプットします。
Qiitaに投稿するのも初めてなので、Markdownもよくわかりませんが、練習して見ようと思います。アプリケーション作成
rails _5.1.6_ new app1.「5.1.6」はバージョン
2.「app」はアプリ名Gemfileを修正して「bundle install」を実行し、gemをインストール
(Gemfileの内容は今後理解する必要あり)
エラーになった場合は「bundle update」する必要あり
(エラーのログに記載されている)ローカル環境にインストールしないようにするためには下記の特殊なフラグを使用する
(HerokuでSQLiteはサポートされていないため、必要になるみたいだがよくわからない)bundle install --without productionHeroku CLIのインストール(Herokuのコマンドラインインターフェイスを利用可能にする)
$ source <(curl -sL https://cdn.learnenough.com/heroku_install)正しくインストールされたかは下記コマンドを実行
$ heroku --versionherokuに新しいアプリケーションの実行場所を作成する
$ heroku creategit&heroku コマンド
$ git add -A $ git commit -m "コミットのメッセージ" $ git checkout master $ git merge 「ブランチ名」 $ git push $ git push heroku $ rails db:migrate $ heroku pg:reset DATABASE $ heroku run rails db:migrate $ heroku run rails db:seed $ heroku restartRails コマンド
フォルダやファイルの自動生成
home_controller.rb
がapp/controllers
に生成され、このファイルの中身にtopメソッドがある
generateはgに省略が可能$ rails generate controller home top
config/routes.rb
内で「get "URL", to: 'コントローラ名#アクション名'」を記述することでtop.html.erb
の内容がブラウザで表示可能get 'home/top', to: 'home#top'アクションの追加方法
generateは生成するという意味なので
rails g ~
は使えません
ルーティングを追加し、アクションを追加する必要があります。routes.rbにルーティングの設定
get 'about', to: 'home#about'
home_controller.rb
にアクションの追加def about endビューを追加
app/views/home
にabout.html.erb
を追加初期表示の変更
ルートURLを設定
root 'コントローラ名#アクション名'コード
繰り返し処理
<% オブジェクト.each do |変数| %> <% end %>link_toメソッド
リンクをメソッド
<%= link_to "リンクの名前", URLまたはルーティングヘルパー %>findメソッド
引数に
id
の値を指定することでそのid
のレコードを取得する
Postテーブルの2レコード目を取得post = Post.find(2)redirect_toメソッド
更新処理等でページを移動する場合に使用
リダイレクトするときはpath
ではなくurl
を使用するredirect ヘルパー名_urlDB
データベースの操作
テーブル作成
マイレグレーションファイルを作成
$ rails g model Post content:textPost・・・テーブル(モデルは単数形)
content:text・・・「カラム名:データ型」ルーティングの確認方法
1.ターミナル
$ rails routers
2.ブラウザ
ブラウザのアドレスの末尾に/rails/info
と入力
- 投稿日:2019-04-15T09:48:25+09:00
仮想マシンの構築からRailsプロジェクト作成まで半自動で実行してくれるスクリプトをつくってみた【MacOS対応】
手軽に作ったり壊したりできるのが仮想環境で開発するメリットのひとつです。
手軽とはいえ、仮想環境の構築からRailsプロジェクトの作成まで行うなると、そこそこの量のコマンドを実行する必要があるのでそれなりに面倒です。
ということで、仮想マシンの構築からRailsプロジェクトの作成までを半自動で実行してくれるシェルスクリプトをつくってみました。
今回つくったスクリプトはドットインストールのローカル開発環境の構築 [macOS編] というレッスン内容を元にしています。ローカル開発環境や仮想環境の概要、仮想環境への接続方法などが分からないという方は、まずこちらのレッスンを受けることをおすすめします。
動作環境
下記の環境で動作を確認しています。ただ、あくまで自分用につくったスクリプトなので必ずしも正しく動作するとは限りません。各コマンドを理解した上で使用してください。
- MacOS Mojave 10.14.4
- VirtualBox 5.2.20
- Vagrant 2.0.3
実行ファイル
以下の3つです。
- virtual_env_setup.command
- rails_setup1.sh
- rails_setup2.sh
GitHubで公開しています。
$ git clone
するなどして入手してください。$ git clone https://github.com/Tatehito/rails-dev-setup.git何ができるのか
このスクリプトを実行すると、以下の環境が完成します。
- VirtualBox(vagrant)を使った仮想開発環境
- CentOS 7.3
- Ruby(任意のバージョンを指定可)
- Rails(任意のバージョンを指定可)
- 任意の名前のRailsプロジェクト(DBはSQLite)
使い方
事前準備
- VirtualBoxのインストール
- Vagrantのインストール
- Cyberduckのインストール
- ホームディレクトリ配下に
workspace
という名前のディレクトリを作成するホームディレクトリ配下の
workspace
ディレクトリに仮想環境用のディレクトリを作成するようにしているため、事前にworkspace
ディレクトリを作成しておいてください。※workspace
以外のディレクトリを指定する方法は後述します。各種ツールのインストール方法はドットインストールのレッスンがわかりやすいです。ローカル開発環境の構築 [macOS編]
スクリプトを実行する
1.virtual_env_setup.commandをMacOSで実行する
「virtual_env_setup.command」は、仮想環境の構築から起動までを実施します。
MacOS上でダブルクリックで実行します。実行すると、仮想マシン用に作成するディレクトリ名を尋ねられるので、任意の名前を入力してEnterを押してください。
Please Enter Virtual-Environment Directory Name. $ 作成するディレクトリ名最後に赤字で下記のようなメッセージが出ますが、問題ありません。
Vagrant was unable to mount VirtualBox shared folders. This is usually because the filesystem "vboxsf" is not available. This filesystem is made available via the VirtualBox Guest Additions and kernel module. (以下略)処理が完了すると、ホームディレクトリ配下の
workspace/入力したディレクトリ/Vagrantfile
が作成されているはずです。なお、この時点で仮想マシンは起動状態になっています。2.構築された仮想環境にシェルを配置する
CyberduckなどのFTPクライアントソフト使って、「rails_setup1.sh」「rails_setup2.sh」を仮想環境のホームディレクトリにアップロードします。
Cyberduckの使い方はドットインストールのレッスン(ローカル開発環境の構築 [macOS編] )が分かりやすいです。
配置したら、ターミナルから
vagrant ssh
で仮想マシンにログインし、配置したシェルの実行権限を下記コマンドで付与します。$ chmod 755 *.sh3.rails_setup1.shを仮想環境で実行する
「rails_setup1.sh」を実行します。「rails_setup1.sh」では、Git、rbenv、ruby-buildのインストールを実施します。
実行したらやることはないので、処理が終わるまで待ちます。
4.rails_setup2.shを仮想環境で実行する
続いて「rails_setup2.sh」を実行します。「rails_setup2.sh」ではRuby、Ruby on Railsのインストール、Railsプロジェクトの作成を実施します。
実行すると、以下のようにRuby、Railsのバージョン、Railsプロジェクト名を入力するよう促されるので、入力します。
Please enter the version of "Ruby" to install. $ 2.5.5 Please enter the version of "Rails" to install. $ 5.2.2 Please enter Rails Project Name. $ sample_project処理が進んでいくと、SQLiteインストール時に以下のメッセージが表示されて処理が一時停止するので、
y
を入力して処理を進めます。総ダウンロード容量: 104 k インストール容量: 366 k Is this ok [y/d/N]:5.Railsサーバー起動、アクセス
処理がすべて終了すると、以下のメッセージがコンソールに出力されます。
Command to start the Rails server:rails s -b 192.168.33.10 URL:http://192.168.33.10:3000/このメッセージにある通り、
$ rails s -b 192.168.33.10
でRailsサーバーを起動し、ブラウザからhttps://192.168.33.10:3000
でRailsアプリケーションに接続できたら完了です。スクリプト内容のちょっとした解説
virtual_env_setup.command
virtual_env_setup.commandecho "Please Enter Virtual-Environment Directory Name." read vspace_name cd ./workspace mkdir $vspace_name # VagrantFileを作成 cd ./${vspace_name} vagrant init bento/centos-7.3
cd ./workspace
でホームディレクトリ配下のworkspaceディレクトリに移動し、仮想環境用のディレクトリを作成するようにしています。workspace以外のディレクトリを指定したければ、
cd ./workspace
で指定している移動先のディレクトリを任意のディレクトリに変更すればOKです。virtual_env_setup.command# 仮想マシンを起動 vagrant up
初回起動は時間がかかるので、処理の最後に起動のコマンドを実行するようにしています。スクリプトの実行が終わったら仮想マシンが起動状態になっているので注意してください。
仮想マシンの状態は
$ vagrant status
で確認できます。rails_setup1.sh
rails_setup1.sh# rbenvのパスを通す echo '# rbenv' >> ~/.bash_profile echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile echo 'eval "$(rbenv init -)"' >> ~/.bash_profile # ログインシェルを再起動し設定を反映 exec $SHELL --loginrails_setup1.shの最後に、ログインシェルの再起動を行っています。これはrbenvのパスの設定を反映させるためです。
rails_setup2.sh
必要なライブラリを順番にインストールし、最後にRailsプロジェクトを作成します。ちなみに、Node.jsをインストールしておかないとRailsサーバー起動時にエラーになります。
rails_setup2.sh# ExecJSランタイム(Node.js)のインストール curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - sudo yum -y install nodejs改善したいポイント
前述したように
$ rails s -b 192.168.33.10
コマンドでRailsサーバーを起動し、http://192.168.33.10:3000/
で接続します。が、本来は
$ rails s
コマンドで起動、http://localost:3000/
で接続できるはずです。(本来と言うか、以前仮想環境つくったときはこれで接続できてました)今回作成したスクリプトではlocalhostで繋げないようになってしまっているので、その点を改善したいと考えています。
おわりに
自分用につくったため汎用的なスクリプトではないですが、複雑なことをやっているわけではないので理解するのは難しくないと思います。
仮想環境の構築に慣れてきて、いちいち手で作るのが面倒だという方はぜひ参考にしてみてください。
- 投稿日:2019-04-15T08:21:49+09:00
No route matches [DELETE] "/users/sign_out" エラー(Rails)
はじめに
初学者の学習アウトプット用記事です。
ご指摘訂正アドバイスは是非お願いします。で、今回のテーマは!!!!!!
エラー!!!!です。
内容としては、deviseでログイン機能を実装してログインはできるのにログアウトするとエラーが起きてしまうということでした。
No route matches [DELETE] "/users/sign_out"
エラー文が
No route matches [DELETE] "/users/sign_out"
なんとなくなんですが、
「DELETEのルーティングされてねぇぞ!!ごらぁああ!!!!」
と言われてる気がしました。
ターミナルにてrake routesコマンド実行してみると、
destroy_user_session GET /users/sign_out(.:format) devise/sessions#destroy #メソッドがGETになってる???ビューファイルのログアウトボタンのリンクのパスは問題なく記述できてました。
sign_outログアウトのメソッドってDELETEじゃないの???????ってことでルーティング確認!!
routes.rbRails.application.routes.draw do devise_for :users root 'groups#index' resources :users, only: [:index,:edit, :update] resources :groups, only: [:new, :create, :edit, :update] do resources :messages, only: [:index, :create] end endあれ???問題なくね????
どこがおかしいんだ?・・・・・
ってことでメンターさんに質問。
メンターさんも??????あれ????なんだろう???とrake routesで確認。
するとやはりGETになってる。試しにroutes.rbファイルのdevise_for :usersの記述を削除
routes.rbRails.application.routes.draw do root 'groups#index' resources :users, only: [:index,:edit, :update] resources :groups, only: [:new, :create, :edit, :update] do resources :messages, only: [:index, :create] end endそしてターミナルでrake routesコマンド!!!!
すると!!!!!
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroyGETがDELETEに変わってる!!!!
そのまま再度、devise_for :usersを記述。
routes.rbRails.application.routes.draw do devise_for :users root 'groups#index' resources :users, only: [:index,:edit, :update] resources :groups, only: [:new, :create, :edit, :update] do resources :messages, only: [:index, :create] end endそんで再度ターミナルでrake routesで確認したらDELETEになっていました。
無事、その後rails sでサーバー再起動させたら問題なくログアウトできました。
とりあえず解決はできたのですが、
今回の件はバグ?みたいなものと説明されましたが真相は謎です。他にも
記事を調べたら
[Rails 4.x] Devise で Sign Out が Routing Error になる際の対応。(method の delete が get になる場合)
https://qiita.com/colorrabbit/items/5545fce7e5cd4e494396の記事がでてきました。
上記の記事の内容を試したのですがこちらは特に変化がなくエラーのままでした。
- 投稿日:2019-04-15T07:56:41+09:00
【3分入門】コピペで導入 railsでgraphql
【3分入門】コピペで導入 ooo シリーズ第一弾です。
rails に graphqlを導入していきます。
https://github.com/nishisuke/graphql-rails-minimum-sample
graphql とは?
https://graphql.org/learn/install
# Gemfile gem 'graphql'$ bundlemodels
users type name String age Integer app/models/user.rbclass User < ApplicationRecord def friends %i[user mate_user].inject(Friend.none) do |friends_query, column_name| friends_query.or(Friend.where(column_name => self)) end end end
friends type user_id Integer mate_user_id Integer app/models/friend.rbclass Friend < ApplicationRecord belongs_to :user belongs_to :mate_user, class_name: :User def pairs [user, mate_user] end endfriend model has two users.
setup
app/graphql/graphql_rails_minimum_sample_schema.rbclass GraphqlRailsMinimumSampleSchema < GraphQL::Schema query(GqlTypes::Query) endapp/graphql/gql_types.rbmodule GqlTypes class Query < GraphQL::Schema::Object field :users, [UserType], null: false field :friends, [FriendType], null: false do argument :user_id, Int, required: true, camelize: false end def users User.all end def friends(user_id:) User.find(user_id).friends end end endapp/graphql/gql_types/base_object.rbmodule GqlTypes class BaseObject < GraphQL::Schema::Object end endapp/graphql/gql_types/friend_type.rbmodule GqlTypes class FriendType < BaseObject field :pairs, [UserType], null: false end endapp/graphql/gql_types/user_type.rbmodule GqlTypes class UserType < BaseObject field :name, String, null: false field :age, String, null: true field :created_at, String, null: false field :friends, [FriendType], null: false end endexecute query!!
注意点
- created_atなどsnake caseのデータ名はデフォルトでcamel caseで指定する
- camelize false を指定すればsnake caseで指定できる
- argumentはvariablesに渡す
- トップレベルの{}に注意(以下)
# queryには{}をつけない query get_friends($user_id: Int!) { # camelize falseなためuserIdではない(:point_up_2: :point_down: ) friends(user_id: $user_id) {} }{ users {} }try
rails c> GraphqlRailsMinimumSampleSchema.execute('{ users { name createdAt age friends { pairs { name } } } }').to_h => {"data"=>{ "users"=>[{ "name"=>"nishi", "createdAt"=>"2019-04-14 04:01:37 UTC", "age"=>"9", "friends"=>[{ "pairs"=>[{"name"=>"nishi"}, {"name"=>"tarou"}] }] }, { "name"=>"suke", "createdAt"=>"2019-04-14 04:01:37 UTC", "age"=>"19", "friends"=>[{ "pairs"=>[{"name"=>"suke"}, {"name"=>"tarou"}] }] }, { "name"=>"tarou", "createdAt"=>"2019-04-14 04:01:37 UTC", "age"=>"20", "friends"=>[ {"pairs"=>[{"name"=>"nishi"}, {"name"=>"tarou"}]}, {"pairs"=>[{"name"=>"suke"}, {"name"=>"tarou"}]} ] }] }}> GraphqlRailsMinimumSampleSchema.execute('query get_friends($user_id: Int!) { friends(user_id: $user_id) { pairs { name } } }', variables: { user_id: User.last.id } ).to_json => {"data"=>{"friends"=>[ {"pairs"=>[{"name"=>"nishi"}, {"name"=>"tarou"}]}, {"pairs"=>[{"name"=>"suke"}, {"name"=>"tarou"}]} ]}}
- 投稿日:2019-04-15T07:32:49+09:00
【Rails】find_or_initialize_byメソッドを使ってインスタンスを作成する時のポイント
現在、amazonAPIを利用した口コミの共有サービスを作成中です。
その中で、「商品を検索し表示させる」という処理があるのですが、その際に役立った
find_or_initialize_by
メソッドについて簡単に整理します。
- 参考記事 Railsガイド
find_or_initialize_byメソッドとは
find_or_initialize_byメソッド
とは、条件に合致したインスタンスがデータベースに保存されているかどうかをチェックしています。この際、
- データベースに保存されている場合は
find
メソッド- データベースに保存されていない場合は'new'メソッド
として、インスタンスの状況によって適用されるメソッドが異なることがポイントです。インスタンスが保存されている場合、findメソッドが適用されるのでインスタンスに保存済みのデータ(idなど)を含めることができます。
インスタンス = persisted?
やインスタンス = new_record?
でデータベースの保存状況を真偽値で取得できます。find_or_initialize_byメソッドの使い道
前述の通り、
find_or_initialize_by
は条件分岐がポイントとなるので、データベースの保存状況でインスタンスに変化を与えたい場合に有用となります。例えば私の場合ですと、APIから商品データを取得し一覧表示しています。
その際に、データベース保存済みなら「商品削除ボタン」を表示、データベースに保存していない新規のインスタンスなら「商品登録ボタン」を表示したいケースで、
find_or_initialize_by
を使用しています。products_controller.rbdef create @product = Product.find_or_initialize_by(asin: params[:product_asin]) unless @product.persisted? # @product が保存されていない場合、先に @product を保存する products = Amazon::Ecs.item_lookup( params[:product_asin], response_group: 'Medium', country: 'jp' ) products.items.each do |item| @product = Product.new( title: item.get('ItemAttributes/Title'), image_url: item.get('LargeImage/URL'), url: item.get('DetailPageURL'), asin: item.get('ASIN'), brand_amazon_name: item.get('ItemAttributes/Brand'), price: item.get('OfferSummary/LowestNewPrice/Amount'), ) @product.save end end end_products.html.erb<!--商品登録削除ボタン--> <div class="buttons text-center"> <% if product.persisted? %> <%= form_tag(product_path(product.id), method: :delete) do %> <%= hidden_field_tag :product_id, product.id %> <%= submit_tag '削除', class: 'btn btn-danger' %> <% end %> <% else %> <%= form_tag(products_path) do %> <%= hidden_field_tag :product_asin, product.asin %> <%= submit_tag '登録', class: 'btn btn-primary' %> <% end %> <% end %>(+α)find_or_create_byメソッドについて
find_or_create_by
メソッドは、find_or_initialize_by
と似た内容のメソッドなので、今後のために簡単に整理。条件に合致したインスタンスがデータベースに保存されているかどうかをチェックしている点は、両者とも同じです。
その際に、
find_or_create_by
メソッドは、
- データベースに保存されている場合は
find
メソッド- データベースに保存されていない場合は'create'メソッド
となることがポイントです。「データベースに保存されていない場合は'create'メソッド」となるのですね。
条件に合致した情報をゴリゴリとデータベースに保存していくというケースに適しているのでしょう。
まとめ
find_or_initialize_byメソッドは、「APIを利用して情報取得→整形しインスタンス作成」のようなケースで役立つことがわかりました。
- 投稿日:2019-04-15T03:09:45+09:00
Ruby on Rails: Google Mapをレスポンシブに対応する
実現したいこと
Wepアプリ開発していると、Google mapを使う時があるかと思います。
そんな時に、ただただマップコードを埋め込むとせっかくのレスポンシブデザインを意識したサイトが崩れてしまいます。
なので、今回はレスポンシブデザインに対応させる方法を共有したいと思う。解決方法
<iframe>
を<div class="gmap">
でカッコって上げることで解決できる。<div class="gmap"><%== @user.map %></div>.gmap{ position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden; } .gmap iframe, .gmap object, .gmap embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%;
- 投稿日:2019-04-15T02:59:09+09:00
macOS Mojave, Nokogiriインストールできない問題 解決メモ
macOS MojaveでNokogiriがインストールできない問題解消のメモ
概要
macOSのアップデート後から、Nokogiri Gemのインストールが痛恨の失敗!!
初心者の私には正直理解不能だったが頑張ってエラーを見てググる、を繰り返してみた。
発生したエラー
" clang -o conftest -I/Users/user_name/.rbenv/versions/2.6.2/include/ruby-2.6.0/x86_64-darwin17 -I/Users/user_name/.rbenv/versions/2.6.2/include/ruby-2.6.0/ruby/backward -I/Users/user_name/.rbenv/versions/2.6.2/include/ruby-2.6.0 -I. -I/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxslt/1.1.33/include -I/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9/include/libxml2 -I/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9/include/libxml2 -I/Users/user_name/.rbenv/versions/2.6.2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Do-not-URI-escape-in-server-side-includes.patch 0002-Remove-script-macro-support.patch 0003-Update-entities-to-remove-handling-of-ssi.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxslt/1.1.33\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"\"" -O3 -Wno-error=shorten-64-to-32 -pipe -I /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2 -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L. -L/Users/user_name/.rbenv/versions/2.6.2/lib -L/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9/lib -L/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxslt/1.1.33/lib -L/usr/local/Cellar/xz/5.2.4/lib -L. -L/Users/user_name/.rbenv/versions/2.6.2/lib -fstack-protector-strong -L/usr/local/lib/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxslt/1.1.33/lib/libexslt.a -lm -liconv -lpthread -llzma -lz /Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9/lib/libxml2.a/Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxslt/1.1.33/lib/libxslt.a -lm -liconv -lpthread -llzma -lz /Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9/lib/libxml2.a -llzma -lruby.2.6-static -framework Security -framework Foundation -lpthread -ldl -lobjc /Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxslt/1.1.33/lib/libexslt.a -lm -liconv -lpthread -llzma -lz /Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9/lib/libxml2.a /Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxslt/1.1.33/lib/libxslt.a -lm -liconv -lpthread -llzma -lz /Users/user_name/Desktop/app/app/vendor/bundler/ruby/2.6.0/gems/nokogiri-1.10.2/ports/x86_64-apple-darwin17.7.0/libxml2/2.9.9/lib/libxml2.a -llzma " checked program was: /* begin */ 1: #include "ruby.h" 2: 3: /*top*/ 4: extern int t(void); 5: int main(int argc, char **argv) 6: { 7: if (argc > 1000000) { 8: int (* volatile tp)(void)=(int (*)(void))&t; 9: printf("%d", (*tp)()); 10: } 11: 12: return 0; 13: } 14: extern void xmlSchemaSetParserStructuredErrors(); 15: int t(void) { xmlSchemaSetParserStructuredErrors(); return 0; } /* end */解決方法
bundle configでビルド時のオプションとして、
--use-system-libraries
と--with-xml2-include
を設定しておくといいらしい!$ bundle config build.nokogiri --use-system-libraries --with-xml2-include=$(brew --prefix libxml2)/include/libxml2解決しました!
参考
An error occurred while installing nokogiri (1.10.0), and Bundler cannot continue.
- 投稿日:2019-04-15T01:57:05+09:00
気付いたこと備忘録
- 投稿日:2019-04-15T01:43:52+09:00
Payjpでカード情報登録 と削除機能を実装する(Rails)
実装する機能と前提条件
Payjp(Pay.jp)を利用してページ内に直接フォームを設置する場合を想定しています。
実装するものとしては下記のとおりです。
- 自作のカード登録フォーム
- カード情報とユーザーの紐づけ
- ユーザーとカードの登録と削除
- 商品の購入(次回の記事で記述)もしSDKを使う場合は別記事をご覧いただくかPAY.JP API 利用ガイド | PAY.JPを触るとイメージをつかみやすいと思います。
バージョン情報
ruby 2.3.1
Rails 5.0.7前提条件
- deviseが導入済みでログインができている(current_userを使うため)
- hamlでの記載(gem 'haml-rails')
1.Payjpのアカウントを作成しよう
Payjpのサイトでアカウントを作成します。
2.APIを確認しよう
ダッシュボードのAPIより確認ができます。
今回はテストモードでの実装なので、テスト秘密鍵とテスト公開鍵を使用します。
3.payjpのgemを設置しよう
下記をgemfileに記載しbandle installを実施します。
gem 'payjp'4.payjp.jsを読み込めるようにしよう
下記の通りに追記します。
app/views/layouts/application.html.haml%html %head %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ %title payjptest %script{src: "https://js.pay.jp/", type: "text/javascript"} -# このscriptを記載 = csrf_meta_tags = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %body = yield5.データベースを作成しよう
下記内容でpayjpのデータを保管するデータベースを作成します。nullはお好みで。
尚、紐づけは以下のとおりです。
- user_id -> Userテーブルのid
- customer_id -> payjpの顧客id
- card_id -> payjpのデフォルトカードid
(デフォルトカードidはトークンとは違います。ここの理解で結構時間をとってしまいました…)db/migrate/20190400000000_create_cards.rbclass CreateCards < ActiveRecord::Migration[5.0] def change create_table :cards do |t| t.integer :user_id, null: false t.string :customer_id, null: false t.string :card_id, null: false t.timestamps end end endちなみにカード情報そのものを保存することは禁止されていますので、
payjpに保管されている情報を顧客idやカードidで呼び出すことで情報取得や支払いなどに対応します。
カード情報非通過化対応のお願い6.コントローラーを作成しよう
下記内容でコントローラーを作成します。
ENV["PAYJP_PRIVATE_KEY"]は環境変数でテスト秘密鍵を設定し読み込みます。app/controllers/card_controller.rbclass CardController < ApplicationController require "payjp" def new card = Card.where(user_id: current_user.id) redirect_to action: "show" if card.exists? end def pay #ここでpayjpとCardのデータベース作成を実施します。 Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] if params['payjp-token'].blank? redirect_to action: "new" else customer = Payjp::Customer.create( description: '登録テスト', #なくてもOK email: current_user.email, #なくてもOK card: params['payjp-token'], metadata: {user_id: current_user.id} ) #念の為metadataにuser_idを入れましたがなくてもOK @card = Card.new(user_id: current_user.id, customer_id: customer.id, card_id: customer.default_card) if @card.save redirect_to action: "show" else redirect_to action: "pay" end end end def delete #PayjpとCardデータベースを削除します card = Card.where(user_id: current_user.id).first if card.blank? else Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] customer = Payjp::Customer.retrieve(card.customer_id) customer.delete card.delete end redirect_to action: "new" end def show card = Card.where(user_id: current_user.id).first if card.blank? redirect_to action: "new" else Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] customer = Payjp::Customer.retrieve(card.customer_id) @default_card_information = customer.cards.retrieve(card.card_id) end end end7.カードの登録画面を作成しよう
今回は登録画面と確認兼削除画面の2つを作成します。デザインはアレンジしてください。
登録画面
app/view/card/new.html.haml= form_tag(card_pay_path, method: :post, id: 'charge-form', name: "inputForm") do %label カード番号 = text_field_tag "number", "", class: "number", placeholder: "半角数字のみ" ,maxlength: "16", type: "text", id: "card_number" %br %label 有効期限 %select#exp_month{name: "exp_month", type: "text"} %option{value: ""} -- %option{value: "1"}01 %option{value: "2"}02 %option{value: "3"}03 %option{value: "4"}04 %option{value: "5"}05 %option{value: "6"}06 %option{value: "7"}07 %option{value: "8"}08 %option{value: "9"}09 %option{value: "10"}10 %option{value: "11"}11 %option{value: "12"}12 %span 月/ %select#exp_year{name: "exp_year", type: "text"} %option{value: ""} -- %option{value: "2019"}19 %option{value: "2020"}20 %option{value: "2021"}21 %option{value: "2022"}22 %option{value: "2023"}23 %option{value: "2024"}24 %option{value: "2025"}25 %option{value: "2026"}26 %option{value: "2027"}27 %option{value: "2028"}28 %option{value: "2029"}29 %span 年 %br %label セキュリティコード = text_field_tag "cvc", "", class: "cvc", placeholder: "カード背面3~4桁の番号", maxlength: "4", id: "cvc" #card_token = submit_tag "追加する", id: "token_submit"最初、= sectionを使っていたのですがうまく行かなかったため
%optionが連続発生し駄長なコードになっているのはご了承ください…確認兼削除画面
app/view/card/show.html.haml%label 登録クレジットカード情報 %br = "**** **** **** " + @default_card_information.last4 %br - exp_month = @default_card_information.exp_month.to_s - exp_year = @default_card_information.exp_year.to_s.slice(2,3) = exp_month + " / " + exp_year = form_tag(card_delete_path, method: :post, id: 'charge-form', name: "inputForm") do %input{ type: "hidden", name: "card_id", value: "" } %button 削除する8.Payjpにデータを送りトークンを取得しよう
提供されているpay.jpのサンプルを参照し一部アレンジしております。
app/assets/javascripts/payjp.jsdocument.addEventListener( "DOMContentLoaded", e => { Payjp.setPublicKey("pk_test_79ae2d2743199a76f3ebbbbb"); //ここに公開鍵を直書き let btn = document.getElementById("token_submit"); //IDがtoken_submitの場合に取得されます btn.addEventListener("click", e => { //ボタンが押されたときに作動します e.preventDefault(); //ボタンを一旦無効化します let card = { number: document.getElementById("card_number").value, cvc: document.getElementById("cvc").value, exp_month: document.getElementById("exp_month").value, exp_year: document.getElementById("exp_year").value }; //入力されたデータを取得します。 Payjp.createToken(card, (status, respnse) => { if (status === 200) { //成功した場合 $("#card_number").removeAttr("name"); $("#cvc").removeAttr("name"); $("#exp_month").removeAttr("name"); $("#exp_year").removeAttr("name"); //データを自サーバにpostしないように削除 $("#card_token").append( $('<input type="hidden" name="payjp-token">').val(response.id) ); //取得したトークンを送信できる状態にします document.inputForm.submit(); alert("登録が完了しました"); //確認用 } else { alert("カード情報が正しくありません。"); //確認用 } }); }); }, false );9.ルートを作成しよう
今回はshow,pay,new,deleteの4つのメゾットがあるので下記の通り追記します。
一部はresoursesで設定してもよいかと思います。config/routes.rbpost 'card/new', to: 'card#new' post 'card/show', to: 'card#show' post 'card/pay', to: 'card#pay' post 'card/delete', to: 'card#delete'10.カードを登録してみよう
テストカードはこちらです。
それ以外を打ち込んだ場合はトークンが発行できずはねられます。
以上でカード登録から削除まで一通り実装できました。
次回はこれを使って商品支払いを実装します。参考
- 投稿日:2019-04-15T01:43:52+09:00
Payjpでカード情報登録と削除機能を実装する(Rails)
実装する機能と前提条件
Payjp(Pay.jp)を利用してページ内に直接フォームを設置する場合を想定しています。
実装するものとしては下記のとおりです。
- 自作のカード登録フォーム
- カード情報とユーザーの紐づけ
- ユーザーとカードの登録と削除
- 商品の購入(次回の記事で記述)
もしSDKを使う場合は別記事をご覧いただくかPAY.JP API 利用ガイド | PAY.JPを触るとイメージをつかみやすいと思います。
バージョン情報
ruby 2.3.1
Rails 5.0.7前提条件
- deviseが導入済みでログインができている(current_userを使うため)
- hamlでの記載(gem 'haml-rails')
1.Payjpのアカウントを作成しよう
Payjpのサイトでアカウントを作成します。
2.APIを確認しよう
ダッシュボードのAPIより確認ができます。
今回はテストモードでの実装なので、テスト秘密鍵とテスト公開鍵を使用します。
3.payjpのgemを設置しよう
下記をgemfileに記載しbandle installを実施します。
gem 'payjp'4.payjp.jsを読み込めるようにしよう
下記の通りに追記します。
app/views/layouts/application.html.haml%html %head %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ %title payjptest %script{src: "https://js.pay.jp/", type: "text/javascript"} -# このscriptを記載 = csrf_meta_tags = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %body = yield5.データベースを作成しよう
下記内容でpayjpのデータを保管するデータベースを作成します。nullはお好みで。
尚、紐づけは以下のとおりです。
- user_id -> Userテーブルのid
- customer_id -> payjpの顧客id
- card_id -> payjpのデフォルトカードid
(デフォルトカードidはトークンとは違います。ここの理解で結構時間をとってしまいました…)db/migrate/20190400000000_create_cards.rbclass CreateCards < ActiveRecord::Migration[5.0] def change create_table :cards do |t| t.integer :user_id, null: false t.string :customer_id, null: false t.string :card_id, null: false t.timestamps end end endちなみにカード情報そのものを保存することは禁止されていますので、
payjpに保管されている情報を顧客idやカードidで呼び出すことで情報取得や支払いなどに対応します。
カード情報非通過化対応のお願い6.コントローラーを作成しよう
下記内容でコントローラーを作成します。
ENV["PAYJP_PRIVATE_KEY"]は環境変数でテスト秘密鍵を設定し読み込みます。
私はdotenvを利用しています。app/controllers/card_controller.rbclass CardController < ApplicationController require "payjp" def new card = Card.where(user_id: current_user.id) redirect_to action: "show" if card.exists? end def pay #payjpとCardのデータベース作成を実施します。 Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] if params['payjp-token'].blank? redirect_to action: "new" else customer = Payjp::Customer.create( description: '登録テスト', #なくてもOK email: current_user.email, #なくてもOK card: params['payjp-token'], metadata: {user_id: current_user.id} ) #念の為metadataにuser_idを入れましたがなくてもOK @card = Card.new(user_id: current_user.id, customer_id: customer.id, card_id: customer.default_card) if @card.save redirect_to action: "show" else redirect_to action: "pay" end end end def delete #PayjpとCardデータベースを削除します card = Card.where(user_id: current_user.id).first if card.blank? else Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] customer = Payjp::Customer.retrieve(card.customer_id) customer.delete card.delete end redirect_to action: "new" end def show #Cardのデータpayjpに送り情報を取り出します card = Card.where(user_id: current_user.id).first if card.blank? redirect_to action: "new" else Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] customer = Payjp::Customer.retrieve(card.customer_id) @default_card_information = customer.cards.retrieve(card.card_id) end end end7.カードの登録画面を作成しよう
今回は登録画面と確認兼削除画面の2つを作成します。デザインはアレンジしてください。
登録画面
app/view/card/new.html.haml= form_tag(card_pay_path, method: :post, id: 'charge-form', name: "inputForm") do %label カード番号 = text_field_tag "number", "", class: "number", placeholder: "半角数字のみ" ,maxlength: "16", type: "text", id: "card_number" %br %label 有効期限 %select#exp_month{name: "exp_month", type: "text"} %option{value: ""} -- %option{value: "1"}01 %option{value: "2"}02 %option{value: "3"}03 %option{value: "4"}04 %option{value: "5"}05 %option{value: "6"}06 %option{value: "7"}07 %option{value: "8"}08 %option{value: "9"}09 %option{value: "10"}10 %option{value: "11"}11 %option{value: "12"}12 %span 月/ %select#exp_year{name: "exp_year", type: "text"} %option{value: ""} -- %option{value: "2019"}19 %option{value: "2020"}20 %option{value: "2021"}21 %option{value: "2022"}22 %option{value: "2023"}23 %option{value: "2024"}24 %option{value: "2025"}25 %option{value: "2026"}26 %option{value: "2027"}27 %option{value: "2028"}28 %option{value: "2029"}29 %span 年 %br %label セキュリティコード = text_field_tag "cvc", "", class: "cvc", placeholder: "カード背面3~4桁の番号", maxlength: "4", id: "cvc" #card_token = submit_tag "追加する", id: "token_submit"最初、= sectionを使っていたのですがうまく行かなかったため
%optionが連続発生し駄長なコードになっているのはご了承ください…確認兼削除画面
app/view/card/show.html.haml%label 登録クレジットカード情報 %br = "**** **** **** " + @default_card_information.last4 %br - exp_month = @default_card_information.exp_month.to_s - exp_year = @default_card_information.exp_year.to_s.slice(2,3) = exp_month + " / " + exp_year = form_tag(card_delete_path, method: :post, id: 'charge-form', name: "inputForm") do %input{ type: "hidden", name: "card_id", value: "" } %button 削除する8.Payjpにデータを送りトークンを取得しよう
提供されているpay.jpのサンプルを参照し一部アレンジしております。
app/assets/javascripts/payjp.jsdocument.addEventListener( "DOMContentLoaded", e => { Payjp.setPublicKey("pk_test_79ae2d2743199a76f3ebbbbb"); //ここに公開鍵を直書き let btn = document.getElementById("token_submit"); //IDがtoken_submitの場合に取得されます btn.addEventListener("click", e => { //ボタンが押されたときに作動します e.preventDefault(); //ボタンを一旦無効化します let card = { number: document.getElementById("card_number").value, cvc: document.getElementById("cvc").value, exp_month: document.getElementById("exp_month").value, exp_year: document.getElementById("exp_year").value }; //入力されたデータを取得します。 Payjp.createToken(card, (status, respnse) => { if (status === 200) { //成功した場合 $("#card_number").removeAttr("name"); $("#cvc").removeAttr("name"); $("#exp_month").removeAttr("name"); $("#exp_year").removeAttr("name"); //データを自サーバにpostしないように削除 $("#card_token").append( $('<input type="hidden" name="payjp-token">').val(response.id) ); //取得したトークンを送信できる状態にします document.inputForm.submit(); alert("登録が完了しました"); //確認用 } else { alert("カード情報が正しくありません。"); //確認用 } }); }); }, false );9.ルートを作成しよう
今回はshow,pay,new,deleteの4つのメゾットがあるので下記の通り追記します。
一部はresoursesで設定してもよいかと思います。config/routes.rbpost 'card/new', to: 'card#new' post 'card/show', to: 'card#show' post 'card/pay', to: 'card#pay' post 'card/delete', to: 'card#delete'10.カードを登録してみよう
テストカードはこちらです。
それ以外を打ち込んだ場合はトークンが発行できずはねられます。
以上でカード登録から削除まで一通り実装できました。
次回はこれを使って商品支払いを実装します。参考
- 投稿日:2019-04-15T01:43:52+09:00
Payjpでクレジットカード登録と削除機能を実装する(Rails)
実装する機能と前提条件
今回、Payjp(Pay.jp)を利用して入力フォームを直接ページ内に設置します。
実装するものとしては下記のとおりです。
- 自作のカード情報入力フォーム
- カード情報とユーザーの紐づけ
- ユーザーとカードの登録と削除
- 商品の購入(次回の記事参照)
もしSDKを使う場合は別記事をご覧いただくかPAY.JP API 利用ガイド | PAY.JPを触るとイメージをつかみやすいと思います。
バージョン情報
・ruby 2.3.1
・Rails 5.0.7前提条件
・deviseが導入済みでログインができている(current_userを使うため)
・hamlでの記載(gem 'haml-rails')1.Payjpのアカウントを作成しよう
Payjpのサイトでアカウントを作成します。
2.APIを確認しよう
ダッシュボードのAPIより確認ができます。
今回はテストモードでの実装なので、テスト秘密鍵とテスト公開鍵を使用します。
3.payjpのgemを設置しよう
下記をgemfileに記載しbandle installを実施します。
gem 'payjp'4.payjp.jsを読み込めるようにしよう
下記の通りに追記します。
app/views/layouts/application.html.haml%html %head %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ %title payjptest %script{src: "https://js.pay.jp/", type: "text/javascript"} -# このscriptを記載 = csrf_meta_tags = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %body = yield5.データベースを作成しよう
下記内容でpayjpのデータを保管するデータベースを作成します。nullはお好みで。
尚、紐づけは以下のとおりです。
- user_id -> Userテーブルのid
- customer_id -> payjpの顧客id
- card_id -> payjpのデフォルトカードid
(デフォルトカードidはトークンとは違います。ここの理解で結構時間をとってしまいました…)db/migrate/20190400000000_create_cards.rbclass CreateCards < ActiveRecord::Migration[5.0] def change create_table :cards do |t| t.integer :user_id, null: false t.string :customer_id, null: false t.string :card_id, null: false t.timestamps end end endちなみにカード情報そのものを保存することは禁止されていますので、
payjpに保管されている情報を顧客idやカードidで呼び出すことで情報取得や支払いなどに対応します。
カード情報非通過化対応のお願い6.コントローラーを作成しよう
下記内容でコントローラーを作成します。
ENV["PAYJP_PRIVATE_KEY"]は環境変数でテスト秘密鍵を設定し読み込みます。
私はdotenvを利用しています。app/controllers/card_controller.rbclass CardController < ApplicationController require "payjp" def new card = Card.where(user_id: current_user.id) redirect_to action: "show" if card.exists? end def pay #payjpとCardのデータベース作成を実施します。 Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] if params['payjp-token'].blank? redirect_to action: "new" else customer = Payjp::Customer.create( description: '登録テスト', #なくてもOK email: current_user.email, #なくてもOK card: params['payjp-token'], metadata: {user_id: current_user.id} ) #念の為metadataにuser_idを入れましたがなくてもOK @card = Card.new(user_id: current_user.id, customer_id: customer.id, card_id: customer.default_card) if @card.save redirect_to action: "show" else redirect_to action: "pay" end end end def delete #PayjpとCardデータベースを削除します card = Card.where(user_id: current_user.id).first if card.blank? else Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] customer = Payjp::Customer.retrieve(card.customer_id) customer.delete card.delete end redirect_to action: "new" end def show #Cardのデータpayjpに送り情報を取り出します card = Card.where(user_id: current_user.id).first if card.blank? redirect_to action: "new" else Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"] customer = Payjp::Customer.retrieve(card.customer_id) @default_card_information = customer.cards.retrieve(card.card_id) end end end7.カードの登録画面を作成しよう
今回は登録画面と確認兼削除画面の2つを作成します。デザインはアレンジしてください。
登録画面
app/view/card/new.html.haml= form_tag(card_pay_path, method: :post, id: 'charge-form', name: "inputForm") do %label カード番号 = text_field_tag "number", "", class: "number", placeholder: "半角数字のみ" ,maxlength: "16", type: "text", id: "card_number" %br %label 有効期限 %select#exp_month{name: "exp_month", type: "text"} %option{value: ""} -- %option{value: "1"}01 %option{value: "2"}02 %option{value: "3"}03 %option{value: "4"}04 %option{value: "5"}05 %option{value: "6"}06 %option{value: "7"}07 %option{value: "8"}08 %option{value: "9"}09 %option{value: "10"}10 %option{value: "11"}11 %option{value: "12"}12 %span 月/ %select#exp_year{name: "exp_year", type: "text"} %option{value: ""} -- %option{value: "2019"}19 %option{value: "2020"}20 %option{value: "2021"}21 %option{value: "2022"}22 %option{value: "2023"}23 %option{value: "2024"}24 %option{value: "2025"}25 %option{value: "2026"}26 %option{value: "2027"}27 %option{value: "2028"}28 %option{value: "2029"}29 %span 年 %br %label セキュリティコード = text_field_tag "cvc", "", class: "cvc", placeholder: "カード背面3~4桁の番号", maxlength: "4", id: "cvc" #card_token = submit_tag "追加する", id: "token_submit"最初、= sectionを使っていたのですがうまく行かなかったため
%optionが連続発生し駄長なコードになっているのはご了承ください…確認兼削除画面
app/view/card/show.html.haml%label 登録クレジットカード情報 %br = "**** **** **** " + @default_card_information.last4 %br - exp_month = @default_card_information.exp_month.to_s - exp_year = @default_card_information.exp_year.to_s.slice(2,3) = exp_month + " / " + exp_year = form_tag(card_delete_path, method: :post, id: 'charge-form', name: "inputForm") do %input{ type: "hidden", name: "card_id", value: "" } %button 削除する8.Payjpにデータを送りトークンを取得しよう
提供されているpay.jpのサンプルを参照し一部アレンジしております。
app/assets/javascripts/payjp.jsdocument.addEventListener( "DOMContentLoaded", e => { Payjp.setPublicKey("pk_test_79ae2d2743199a76f3ebbbbb"); //ここに公開鍵を直書き let btn = document.getElementById("token_submit"); //IDがtoken_submitの場合に取得されます btn.addEventListener("click", e => { //ボタンが押されたときに作動します e.preventDefault(); //ボタンを一旦無効化します let card = { number: document.getElementById("card_number").value, cvc: document.getElementById("cvc").value, exp_month: document.getElementById("exp_month").value, exp_year: document.getElementById("exp_year").value }; //入力されたデータを取得します。 Payjp.createToken(card, (status, respnse) => { if (status === 200) { //成功した場合 $("#card_number").removeAttr("name"); $("#cvc").removeAttr("name"); $("#exp_month").removeAttr("name"); $("#exp_year").removeAttr("name"); //データを自サーバにpostしないように削除 $("#card_token").append( $('<input type="hidden" name="payjp-token">').val(response.id) ); //取得したトークンを送信できる状態にします document.inputForm.submit(); alert("登録が完了しました"); //確認用 } else { alert("カード情報が正しくありません。"); //確認用 } }); }); }, false );9.ルートを作成しよう
今回はshow,pay,new,deleteの4つのメゾットがあるので下記の通り追記します。
一部はresoursesで設定してもよいかと思います。config/routes.rbpost 'card/new', to: 'card#new' post 'card/show', to: 'card#show' post 'card/pay', to: 'card#pay' post 'card/delete', to: 'card#delete'10.カードを登録してみよう
テストカードはこちらです。
それ以外を打ち込んだ場合はトークンが発行できずはねられます。
以上でカード登録から削除まで一通り実装できました。
次回はこれを使って商品支払いを実装します。参考
- 投稿日:2019-04-15T00:26:55+09:00
Railsでデプロイする際に躓いた箇所
Railsでデプロイする際に躓いた箇所がいくつか(というより沢山)あったので自分用メモも兼ねて書きます。
secret_key_base周り
Rails5.2からsecrets.ymlの代わりにcredentials.yml.encが生成されるようになりました。
rails newされると自動でapp/configにcredentials.yml.encとmaster.keyが生成されます。
master.keyが無い状態でrails credentials:editコマンドを実行するとmaster.keyが生成されますが、生成されたmaster.keyで復号できず困りました。Rails 5.2 で ActiveSupport::MessageEncryptor::InvalidMessage
こちらの記事にある通り、ローカルにあるmaster.keyの中身をコピーしてproduction環境のmaster.keyに貼り付けたところいけました。
MySQLでAccess denied
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)このようなエラーが出てきて入れず。
どうやら自動で仮パスワードが発行されているようなので調べてみると、
cat /var/log/mysqld.log | grep password 2019-04-14T11:01:59.067618Z 1 [Note] A temporary password is generated for root@localhost: **********となっていたのでこちらの仮パスワードで無事いけました。
Unicornが起動できない
Unicornを起動しようとしたところ以下のようなエラーが。
master failed to start, check stderr log for detailslog/unicorn.logをチェックしたところ、
/home/fkdolly/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/unicorn-5.5.0/lib/unicorn.rb:49:in `block in builder': wrong number of arguments (given 0, expected 2) (ArgumentError)調べてみるとUnicorn 5.5.0で出ているエラーのようでした。
Unicorn で Rails アプリが起動しなかったので対処
Unicorn Refreshing Gem Listbundle exec gem list | grep unicorn unicorn (5.5.0)同じく5.5.0でしたので、
Gemfilegroup :production, :staging do gem 'unicorn', '5.4.1' endbundle installこれでいけるかなと思ったらまだエラー。
5.5.0を削除するのを忘れていました。bundle exec gem uninstall unicorn -v '5.5.0' bundle updateこれで無事に起動できました。
- 投稿日:2019-04-15T00:26:51+09:00
【第5章】rails tutorial 備忘録
レイアウト
bootstrap
yield
ページごとの内容を挿入する
link_to
<%= link_to "表示文字列”,"パス",class:"class名" %>
link_to image_tag
<%= link_to image_tag("画像名",
alt:"alt名" %>
app/assets/image/にあるところから画像を探して、表示してくれる。mv コマンド
bootstrap
gemgileに
gem 'bootstrap-sass', '3.3.7'を追加$touch app/assets/stylesheets/custom.scssでカスタムCSSを作り、そこへcssを記載する。
そこへ
app/assets/stylesheets/custom.scss@import "bootstrap-sprockets"; @import "bootstrap"; を記載する。CSSを追加
remとem
@@@@@@@
letter-spacing
text-transformパーシャル(partial)
app/views/layouts/application.html.erb<!DOCTYPE html> <html> <head> <title><%= full_title(yield(:title)) %></title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> ここから <!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]--> ここまでを ↓ <%= render 'layouts/shim' %> に置き換え、切り出す。 </head> ここから <header class="navbar navbar-fixed-top navbar-inverse"> <div class="container"> <%= link_to "sample app","#",id:"logo" %> <nav> <ul class ="nav navbar-nav navbar-right"> <li><%= link_to "Home",'#' %></li> <li><%= link_to "About",'#' %></li> <li><%= link_to "Log in",'#' %></li> </ul> </nav> </div> </header> ここまでを ↓ <%= render 'layouts/header' %> に置き換え、切り出す <body> <div class = "container"> <%= yield %> </div> </body> </html>切り出したものを
layouts/_shim.html.erb
layouts/_header.html.erb
のファイルに記載する。アセットパイプライン
三つのassetsがある
1 app/assets 今あるアプリケーション固有のアセット2 lib/assets 自分の開発チームによって作られたライブラリ用のアセット
3 vendor/assets サードパーティのアセット
マニフェストファイル
上記のアセットをどのように一つにまとめるかを指示できる
sass
このあと、progateでやろう。
ルートURL
root_pathは 「/」を返す。
root_urlは「http://www.example.com/」(
完全なurl)を返すHTTPの標準では、リダイレクトの時は、完全なurlが求められるが、path書式でも動く。
get 'static_page/help'を
get '/help' ,to: 'static_pages#help’に変換すると
テストとviewsで名前付きurl(
help_path)が使えるようになる。テストで使うルートの書式を名前付きルートに変えてみる。
<%= link_to "About", 'about_path' %>注意!
名前ルートを''で囲わないこと。
統合テスト
アプリケーションにアクセスするところから
隅々までテストするrails g controllerで自動作成されたテストと内容は同じで、
require 'test_helper' class SiteLayoutTest < ActionDispatch::IntegrationTest # test "the truth" do # assert true # end endactionDispatch::IntegrationTestを継承したクラスが記載されている。
単体テスト、機能テスト、統合テストと
様々なテストがある。調べる
各テストのクラスがどんなクラスを継承しているか確認する
継承したクラスによって、意味や動きはどう変わるのか何をrails newしたら、どのtestファイルが作成されるのかも整理する
- 投稿日:2019-04-15T00:10:36+09:00
エンジニア初心者がRailsでランキング機能実装の際につまづいたところ
CDの発売日を管理できるサービスを作っていて、発売日が過ぎたときにランキングから除外しなきゃ!と思ったものの微妙に詰まったのでここに備忘録として書き残しておきます。?
環境:cloud9(IDE)EC2(仮想サーバー)rails(rubyFW)mysql(DB)
まず大前提の知識としてModelはDBの情報を引っ張ってくるということです!(今更)
MVCのそれぞれの役割をしっかり理解しておくことは本当に重要で、理解してプログラミングをしていると今自分が何をやっているのか頭の中で整理できます。今回は実際に色々試した過程を書きます。
大まかな流れとして、
1.DB設計を考える 2.mysql(DB)でコマンドを色々試す→3.処理が成功したらmodelに実装
という形で行いました。1.DB設計を考える
ランキングは中間テーブル(relationships)で集計しているので、中間テーブルに発売日カラムを登録することで発売日でフィルターをかけることができるのでは?
2.mysqlでコマンドを色々試す
▼カラム追加(mysql)
alter table relationships add sales_date date;
楽天apiから発売日情報を文字列型で引っ張って来ているのでエラーになってしまった。
alter table relationships add sales_date varchar(255);
文字列型で登録〜うん良さそう▼発売日を過ぎたものは非表示にするコマンドをチェック
私が実際にやったときはmodelの記述を先に行ってしまったのですごい時間を食ってしまった…先にこっちで確認すべきだった…良い学び
select * from relationships where sales_date > date_format(current_date(),'%Y年%m月%d日');
処理内容としては、現在日時をdate_formatを用いて年月日に変更し、sales_dateと比較演算子を用いて比較しています。これをそのままmodelに実装します。3.処理が成功したらmodelに実装
▼記述方法
relationship.rbdef Relationship.ranking Relationship.where().group().order().limit().count() end前述の通り、modelはdbから情報を引っ張ってくるので書き方としてはかなりdbに近いです。
まずwhereで絞り込み、groupで重複した値をまとめ、orderで並べ替え、limitで表示制限をして最後のcountでCDの登録された数を数えるといった流れです。実際のコードを書いていきます。relationship.rbdef self.ranking self.where("sales_date > date_format(current_date(),'%Y年%m月%d日')").group(:item_id).order('count_item_id DESC').limit(12).count(:item_id) endwhere以外はそこまで特別なことはしていないので省きます。
結論から書くとwhereにdbで成功した文をダブルクォーテーションで囲むだけでOKです!笑
これでできたときは拍子抜けしました…それと同時にMVCの理解度が低かったとかなり痛感しました。
modelはdbの情報を引っ張ってくるわけだからdbで実際に成功した文をそのまま書けば確かに間違いはないですねwまとめ
MVCの役割を理解することの重要性を書きたかったのですがシッチャカメッチャカになっちゃった感。。。
まあそれなりに自分の考えは整理できた気がするので良しとします笑
反省点としては何を書くのか考えていなかったこと、考えをまとめていなかったことの二点ですかね?精進します!