- 投稿日:2019-08-20T23:15:04+09:00
素人による "and return unless"
Railsチュートリアル11章リスト11.40にて
以下のコードがあった。
def show @user = User.find(params[:id]) redirect_to root_url and return unless @user.activated? endこのコードの中の
and return unless
の挙動が分からなかったので、調べて考えたことをまとめておく。
and return
についてまずは
and return
について見てみよう。Railsガイドにて以下の解説と参考コードがあった。Rails開発をやっていれば、一度は "Can only render or redirect once per action" エラーに遭遇したことがあるでしょう。いまいましいエラーですが、修正は比較的簡単です。このエラーはほとんどの場合、開発者がrenderメソッドの基本的な動作を誤って理解していることが原因です。
def show @book = Book.find(params[:id]) if @book.special? render action: "special_show" end render action: "regular_show" end上のコードでは、
@book.special?
がtrue
の時、if
文内のrender
とその外のrender
も実行されてしまい、二重レンダリングというエラーになる。そこで、and return
を使って明示的にメソッドを抜けることで二重レンダリングを避ける。def show @book = Book.find(params[:id]) if @book.special? render action: "special_show" and return end render action: "regular_show" end挙動としては、
render
やredirect_to
の戻り値がtrue
なので、and
の後ろのreturn
が実行されるということだ。なお、
&& return
を使うとこの場合正しく動作しない。というのも、&&
は優先度が高いのでrender action: ("special_show" && return)
ということになるからだろう。一方のand
の優先度は超低い。and return
はこのand
の優先度の低さを上手に利用している。
and return unless
について
and return
の働きとand
の優先度について書いたので、あとはそれを組み合わせるだけだ。もう一度最初のコードを見てみよう。def show @user = User.find(params[:id]) redirect_to root_url and return unless @user.activated? end
and
の優先順位は低いので、redirect_to root_url
が先に評価されるので、and
が評価するのはredirect_to root_url
とreturn
になる。()でくくってやると以下のようになる。(redirect_to root_url) and (return)あとは、上のカタマリがunlessの後置修飾がついているだけだ。つまり、
redirect_to root_url and return unless @user.activated?
は以下と同じになる。unless @user.activated? redirect_to root_url and return endおわり
and return unless
というカタマリで見てしまったので挙動が見えず分からなくなってしまったが、ひとつずつ分解して見てみるとそこまで恐ろしいものでもなかった。「巨大で恐ろしい相手でも、ひとつひとつは取るに足らないものだぞ」と人生の教訓をプログラミングが教えてくれた。
- 投稿日:2019-08-20T19:05:03+09:00
Rails チュートリアル(3章、4章)をRSpecでテスト
はじめに
なんとなく、RSpecの書き方がわかってきたので、Rails チュートリアルのテストを書いて見ました。
Rails チュートリアル 3,4章
RSpecの導入
gemを入れます。
gemfilegroup :development, :test do gem 'factory_bot_rails' gem 'rspec-rails', '~> 3.8' gem 'shoulda-matchers' #後の章で使うのでとりあえず入れてます。 end$ bundle install$ rails generate rspec:installDBを作成していなければ、
rails db:create
で作成してください。作ってなく警告が出ました。RSpecの設定
以下を参考にしました。↓
RailsでRSpecの初期設定を行う際のテンプレートを作ってみる-Qiita.rspec--require rails_helper --format documentationconfig/application.rbmodule SampleApp class Application < Rails::Application config.load_defaults 5.2 #----------ここから下を追加--------------------------- config.generators do |g| g.test_framework :rspec, helper_specs: false, routing_specs: false, view_specs: false, controller_specs: false end #----------ここまで----------------------------------- config.generators.system_tests = nil end endRSpecを利用したコントローラの機能テストは、Rails5からはrequest specで記述することが推奨されてるみたいなので、controller_specsも省きました。
以下を参考にしました。↓
Rails5でコントローラのテストをController specからRequest specに移行する-Qiita
everydayrails
Project: RSpec Rails 3.8spec/rails_helper.rbRSpec.configure do |config| config.include FactoryBot::Syntax::Methods endテストを書く(3章、4章)
3章と4章のテストを書きます。
4章のテストを書いてます。元のテスト↓
4.1.2 カスタムヘルパー -Ruby on Rails チュートリアルspec/requests/access_to_static_pages_spec.rbrequire 'rails_helper' describe 'Access to static_pages', type: :request do context 'GET #home' do before do get root_path end it 'response successfully' do expect(response).to have_http_status 200 end it "title is 'Ruby on Rails Tutorial Sample App'" do expect(response.body).to include 'Ruby on Rails Tutorial Sample App' expect(response.body).to_not include '| Ruby on Rails Tutorial Sample App' end end context 'GET #help' do before do get help_path end it 'response successfully' do expect(response).to have_http_status 200 end it "title is 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include 'Help | Ruby on Rails Tutorial Sample App' end end context 'GET #about' do before do get about_path end it 'respose successfully' do expect(response).to have_http_status 200 end it "title is 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include 'About | Ruby on Rails Tutorial Sample App' end end end以上で3章と4章のテストが完了です。
5章で変更するルートはここで変更してしまってます。
また、contactアクションをつくることになってますが、省いてます。request specのファイル名はなんて書けばいいかわからず、なんとなくで書いてしまいました。
Railsチュートリアル 5章
5章のルートのテストは4章でついで書いてしまったので、残りのレイアウトのテストを書きます。
system specの準備
gemfile+ gem 'capybara' + gem 'webdrivers' - #gem 'chromedriver-helper' #削除$ bandle installspec/spec_helper.rbrequire 'capybara/rspec' #これも追加 RSpec.configure do |config| config.include FactoryBot::Syntax::Methods #-------------ここから追加----------------------------- config.before(:each, type: :system) do driven_by :selenium_chrome_headless end #-------------ここまで-------------------------------- end最後にspecフォルダーにrequestsフォルダーを作り、その中にテストファイルを作ります。
テストを書く(5章)
ホームページのリンクのテストを書きます。
元のテスト↓
5.3.4 リンクのテスト Ruby on Railsチュートリアルsystems/site_layout_spec.rbrequire 'rails_helper' RSpec.describe 'site layout', type: :system do it 'has links sach as root_path, help_path and about_path' do visit root_path expect(page).to have_link nil, href: root_path, count: 2 expect(page).to have_link 'Help', href: help_path expect(page).to have_link 'About', href: about_path end end一つのページにリンクがそろっているかのテストなので、itで分けませんでした。正しいかはわかりません。
次に以前書いたタイトルテストをリファクタリングします。テストでも
full_title
ヘルパーを使います。元のテスト↓
演習 Ruby on Railsチュートリアルspec/spec_helper.rbRSpec.configure do |config| config.include FactoryBot::Syntax::Methods config.before(:each, type: :system) do driven_by :selenium_chrome_headless end config.include ApplicationHelper #追加 endspec/requests/access_to_static_pages_spec.rbrequire 'rails_helper' RSpec.describe 'Access to static_pages', type: :request do context 'GET #home' do before do get root_path end it 'response successfully' do expect(response).to have_http_status 200 end it "title is 'Ruby on Rails Tutorial Sample App'" do expect(response.body).to include full_title('') #変更部分 expect(response.body).to_not include '| Ruby on Rails Tutorial Sample App' end end context 'GET #help' do before do get help_path end it 'response successfully' do expect(response).to have_http_status 200 end it "title is 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include full_title('Help') #変更部分 end end context 'GET #about' do before do get about_path end it 'respose successfully' do expect(response).to have_http_status 200 end it "title is 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include full_title('About') #変更部分 end end end次にapplication_helperのテストを書きます。(
full_title
ヘルパーのテストです)
specフォルダーにhelpersフォルダーを作成し、その中にテストファイルを作ります。helpers/application_helper_spec.rbrequire 'rails_helper' RSpec.describe ApplicationHelper, type: :helper do describe '#full_title' do it { expect(full_title('')).to eq 'Ruby on Rails Tutorial Sample App' } it { expect(full_title('Help')).to eq 'Help | Ruby on Rails Tutorial Sample App' } end endひとまず、ここまでです。
- 投稿日:2019-08-20T19:05:03+09:00
Rails チュートリアル(3章、4章、5章)をRSpecでテスト
はじめに
なんとなく、RSpecの書き方がわかってきたので、Rails チュートリアルのテストを書いて見ました。
Rails チュートリアル 3,4章
RSpecの導入
gemを入れます。
gemfilegroup :development, :test do gem 'rspec-rails', '~> 3.8' end$ bundle install$ rails generate rspec:installDBを作成していなければ、
rails db:create
で作成してください。作ってなく警告が出ました。RSpecの設定
以下を参考にしました。↓
RailsでRSpecの初期設定を行う際のテンプレートを作ってみる-Qiita.rspec--require rails_helper --format documentationconfig/application.rbmodule SampleApp class Application < Rails::Application config.load_defaults 5.2 #----------ここから下を追加--------------------------- config.generators do |g| g.test_framework :rspec, helper_specs: false, routing_specs: false, view_specs: false, controller_specs: false end #----------ここまで----------------------------------- config.generators.system_tests = nil end endRSpecを利用したコントローラの機能テストは、Rails5からはrequest specで記述することが推奨されてるみたいなので、controller_specsも省きました。
以下を参考にしました。↓
Rails5でコントローラのテストをController specからRequest specに移行する-Qiita
everydayrails
Project: RSpec Rails 3.8テストを書く(3章、4章)
static_pagesコントローラーのテスト
4章のテストを書いてます。元のテスト↓
4.1.2 カスタムヘルパー -Ruby on Rails チュートリアルspec/requests/access_to_static_pages_spec.rbrequire 'rails_helper' RSpec.describe 'Access to static_pages', type: :request do context 'GET #home' do before { get root_path } it 'responds successfully' do expect(response).to have_http_status 200 end it "has title 'Ruby on Rails Tutorial Sample App'" do expect(response.body).to include 'Ruby on Rails Tutorial Sample App' expect(response.body).to_not include '| Ruby on Rails Tutorial Sample App' end end context 'GET #help' do before { get help_path } it 'responds successfully' do expect(response).to have_http_status 200 end it "has title 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include 'Help | Ruby on Rails Tutorial Sample App' end end context 'GET #about' do before { get about_path } it 'responds successfully' do expect(response).to have_http_status 200 end it "has title 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include 'About | Ruby on Rails Tutorial Sample App' end end end以上で3章と4章のテストが完了です。
5章で変更するルートはここで変更してしまってます。
また、contactアクションをつくることになってますが、省いてます。request specのファイル名はなんて書けばいいかわからず、なんとなくで書いてしまいました。
Railsチュートリアル 5章
5章のルートのテストは4章でついで書いてしまったので、残りのレイアウトのテストを書きます。
system specの準備
gemfile+ gem 'capybara' + gem 'webdrivers' - #gem 'chromedriver-helper' #削除$ bandle installspec/spec_helper.rbrequire 'capybara/rspec' #これも追加 RSpec.configure do |config| config.include FactoryBot::Syntax::Methods #-------------ここから追加----------------------------- config.before(:each, type: :system) do driven_by :selenium_chrome_headless end #-------------ここまで-------------------------------- end最後にspecフォルダーにrequestsフォルダーを作り、その中にテストファイルを作ります。
テストを書く(5章)
site_layoutのテスト
ホームページのリンクのテストを書きます。
元のテスト↓
5.3.4 リンクのテスト -Ruby on Railsチュートリアルsystems/site_layout_spec.rbrequire 'rails_helper' RSpec.describe 'site layout', type: :system do context 'access to root_path' do before { visit root_path } subject { page } it 'has links sach as root_path, help_path and about_path' do is_expected.to have_link nil, href: root_path, count: 2 is_expected.to have_link 'Help', href: help_path is_expected.to have_link 'About', href: about_path end end end一つのページにリンクがそろっているかのテストなので、itで分けませんでした。正しいかはわかりません。
application_helperのテスト
次に以前書いたタイトルテストをリファクタリングします。テストでも
full_title
ヘルパーを使います。元のテスト↓
演習 -Ruby on Railsチュートリアルspec/spec_helper.rbRSpec.configure do |config| config.include FactoryBot::Syntax::Methods config.before(:each, type: :system) do driven_by :selenium_chrome_headless end config.include ApplicationHelper #追加 endspec/requests/access_to_static_pages_spec.rbrequire 'rails_helper' RSpec.describe 'Access to static_pages', type: :request do context 'GET #home' do before { get root_path } it 'responds successfully' do expect(response).to have_http_status 200 end it "has title 'Ruby on Rails Tutorial Sample App'" do expect(response.body).to include full_title('') #変更部分 expect(response.body).to_not include '| Ruby on Rails Tutorial Sample App' end end context 'GET #help' do before { get help_path } it 'responds successfully' do expect(response).to have_http_status 200 end it "has title 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include full_title('Help') #変更部分 end end context 'GET #about' do before { get about_path } it 'responds successfully' do expect(response).to have_http_status 200 end it "has title 'Home | Ruby on Rails Tutorial Sample App'" do expect(response.body).to include full_title('About') #変更部分 end end end次にapplication_helperのテストを書きます。(
full_title
ヘルパーのテストです)
specフォルダーにhelpersフォルダーを作成し、その中にテストファイルを作ります。helpers/application_helper_spec.rbrequire 'rails_helper' RSpec.describe ApplicationHelper, type: :helper do describe '#full_title' do it { expect(full_title('')).to eq 'Ruby on Rails Tutorial Sample App' } it { expect(full_title('Help')).to eq 'Help | Ruby on Rails Tutorial Sample App' } end endusersコントローラーのテスト
元のテスト↓
5.4.1 Usersコントローラ -Ruby on Railsチュートリアルrequests/access_to_users_spec.rbrequire 'rails_helper' RSpec.describe 'access to users', type: :request do describe 'GET #new' do it 'responds successfully' do get signup_path expect(response).to have_http_status 200 end end endsite_layoutのテスト(signupページについて)
元のテスト↓
演習 -Usersコントローラ -Ruby on Railsチュートリアルsystems/site_layout_spec.rbrequire 'rails_helper' RSpec.describe 'site layout', type: :system do #上記省略 context 'access to signup_path' do before { visit signup_path } subject { page } it "has 'Sign up' contens and includes 'Sign up' at title" do is_expected.to have_content 'Sign up' is_expected.to have_title full_title('Sign up') end end endここまで5章が終わりです。
- 投稿日:2019-08-20T17:23:34+09:00
ガイドのための掲示板式マッチングサービスGuide Searchをつくった
はじめに
TechAcademyのWebアプリケーションコースを2か月間受講してオリジナルサービスを作りました。その過程で役に立った知識をまとめていきます。
Guide Search :https://guide-search.herokuapp.com/
TechAcademyのWebアプリケーションコースを受講する経緯などはこのページにまとめてあります。
https://yokubarilink.com/techacademy-learningdeliverable/Guide Searchの説明
アプリの仕組みとしては、家庭教師の募集の掲示板のように掲示板の形式でマッチングを行います。ガイドを募集する側は募集の投稿を行います。一方ガイドをしたい側は、掲示板を見ながら自分にあったサービスに応募するという仕組みです。
主な機能は:
・userの作成、編集、退会
・投稿の作成、編集、削除
・ログイン機能
・投稿の検索
・フォロー機能具体的な作成の流れ
基本はTechAcademyのWebアプリケーションコースでつくったTwitterクローンをもとにしています。
Ruby on Rails チュートリアルで学べることと基本は変わりません追加で実装した機能と参考にしたサイトをまとめていきます。
・検索機能
https://qiita.com/yusuko/items/cff4e46aeafbc3beecf2
https://qiita.com/mochikichi321/items/5c9630c5d87b47130942・投稿一覧に自分の投稿以外を並べる
https://teratail.com/questions/62493・退会機能
https://qiita.com/kenzoukenzou104809/items/d52054000c16cb363707
https://teratail.com/questions/200344難しかった点・課題・今後実装したい機能
・慣れないうちは、このコードをどこに書けばいいのかなどわからないことだらけです。機能の実装を繰り返すうちに感覚を身につけ、それから本質的な理解に移ればいいと思います。
・今後はDM(ダイレクトメール)機能・管理者の機能・ガイドする側とされる側でUserテーブルを分けるなど…
- 投稿日:2019-08-20T17:17:50+09:00
Amazon Linux + Rails + Nginx環境にLet's Encryptを導入する
テスト環境やステージング環境で、SSLを導入する際に、手軽にLet's Encryptを使うという場面が出てくると思う。今回は、Amaxon Linux + Rails + Nginxの環境にLet's Encryptを導入する際にいくつかハマったところがあったのでメモをする。
ちなみに、Amazon Linux2ではcertbotは正式にサポートされていないので、本番環境ではやめたほうがいいかもしれません。ただ、正常に動作しています。以下の注意文言は、チュートリアル: Amazon Linux 2 に SSL/TLS を設定する - Amazon Elastic Compute Cloud より。
Certbot は Amazon Linux 2 で公式にサポートされていませんが、ダウンロードすることができ、
インストールすると正常に機能します。データを保護し、問題を回避するため、次のバックアップを作成しておくことをお勧めします。環境情報
- Amazon Linux AMI release 2018.03
- Rails 5.2.1
- Nginx 1.14.1
導入手順
certbotの導入
certbotをgitからcloneするだけです。作業用ディレクトリの
/usr/local/
に今回は落としました。$ cd /usr/local $ git clone https://github.com/certbot/certbotこのcertbotを使うことでSSLの導入を行うことができます。
$ cd certbot $ ./certbot-auto --helphelpコマンドが動作していれば導入は成功です。
SSL証明書の発行をする前に、nginxを落としておきましょう。
なんか証明書の発行がうまくいかなかったので。。。$ sudo nginx -s stopSSLの証明書の発行
導入しようとしたら、Let's Encryptが正式にサポートされていないため、バックアップをとってから、
--debug
オプションをつけて実行してくださいとのエラーが出てきました。なので、念の為、AMIでバックアップをとりました。debugオプションなし時のエラー内容$ ./certbot-auto certonly --standalone -t FATAL: Amazon Linux support is very experimental at present... if you would like to work on improving it, please ensure you have backups and then run this script again with the --debug flag! Alternatively, you can install OS dependencies yourself and run this script again with --no-bootstrap.改めて、Amazon LinuxでLet's Encryptを入れる方はdebugオプションをつけて実行。
$ ./certbot-auto certonly --standalone -t --debug Creating virtual environment... Traceback (most recent call last): File "<stdin>", line 27, in <module> File "<stdin>", line 19, in create_venv File "/usr/lib64/python2.7/subprocess.py", line 185, in check_call retcode = call(*popenargs, **kwargs) File "/usr/lib64/python2.7/subprocess.py", line 172, in call return Popen(*popenargs, **kwargs).wait() File "/usr/lib64/python2.7/subprocess.py", line 394, in __init__ errread, errwrite) File "/usr/lib64/python2.7/subprocess.py", line 1047, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory今度は、pythonのファイルがない?のかエラーになりました。
どうやら、使用するpythonのバージョンが古かったぽいので、2.7を使うように設定。alternatives --set python /usr/bin/python2.7再度、コマンドを実行すると以下のようになります。
./certbot-auto certonly --standalone -t --debug Creating virtual environment... Installing Python packages... Installation succeeded. Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator standalone, Installer None Enter email address (used for urgent renewal and security notices) (Enter 'c'メールアドレスを入力して、
------------------------------------------------------------------------------- Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree in order to register with the ACME server at https://acme-v01.api.letsencrypt.org/directory ------------------------------------------------------------------------------- (A)gree/(C)ancel: A- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ドメインを聞かれるので、ドメインを入力します。
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel): test.hoge.jpすると、以下のような文言が出てきました。これでどうやら証明書の発行は完了らしい。
MPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/test.hoge.jp/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/test.hoge.jp/privkey.pem Your cert will expire on 2019-11-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le証明書が
/etc/letsencrypt/live/
の下に発行されるので、これを読み込むようにNginxであとは設定するだけ。Nginxの設定
443ポートのリクエストを受け付けるように設定して、証明書のパスを記述。
また、Railsの場合は、proxy_set_header X-FORWARDED_PROTO https;
を忘れずに。詳しい解説は以下が参考になります。nginx.confserver { listen 443 ssl default deferred; ssl_certificate /etc/letsencrypt/live/test.hoge.jp/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/test.hoge.jp/privkey.pem; # <中略> # } location / { add_header Access-Control-Allow-Origin *; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # httpsの設定をしてあげないとRailsの方でSSL判定できずに無限ループに陥る proxy_set_header X-FORWARDED_PROTO https; proxy_set_header Host $http_host; proxy_redirect off; if (!-f $request_filename) { proxy_pass http://app; break; } }Nginxの設定ができたら、再起動しましょう。
$ sudo service nginx startRails側の設定
production環境はデフォルトでSSL設定されていると思いますが、今回はテスト環境だったので、以下を追記。
これにより、httpでアクセスされたものも、Rails側でリダイレクトさせることができます。config/environments/test.rbconfig.force_ssl = true上述しましたが、この設定をする場合はnginxのconfni
proxy_set_header X-FORWARDED_PROTO https;
を記述して、
アプリケーション側にhttpsでのアクセスであることを伝えるようにしないと無限ループになりますので、注意です!参考
チュートリアル: Amazon Linux 2 に SSL/TLS を設定する - Amazon Elastic Compute Cloud
alternatives で python を 2.7に切り替える - Qiita
- 投稿日:2019-08-20T14:06:33+09:00
Rails 6.0.0 のAction Textを使ってみた(Herokuにデプロイするまで)
Rails6がついに来た!
というわけで,主要機能の1つ,Action Textを早速試してみました。
開発環境
- macOS Mojave 10.14.5
- Ruby 2.6.3
- Rails 6.0.0
- Yern 1.17.3
参考
手順
1. アプリの準備
Yarn
とWebpack
が必要です。- MySQLを指定していますが,お好みで。
コンソール$ brew install yarn $ rails new action_text_sample -d mysql --webpack
Rails 6
とimage_processing
をインストールするためGemfileを編集します。
gem 'actiontext'
はRails 6
に標準実装されているので不要coffee-rails
を5.0.0にしないと警告が出るので一応Gemfile- gem 'rails' - gem 'coffee-rails' + gem 'rails', '~> 6.0.0' + gem 'coffee-rails', '~> 5.0' + gem 'image_processing', '~> 1.9.3' - gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
bundle install
がエラーになるので,bundle update
を使用Action Text
をインストール- この記事では
scaffold
でサボりますが,お好みで。コンソール$ bundle update $ rails db:create $ rails g scaffold Post title:string $ rails action_text:install $ rails db:migrate2. Action Textの導入
- WebpackでJavaScriptを利用するためにタグを変更します。
(この作業をとばすとActionTextが反映されません)app/views/layouts/application.html.erb- <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> + <%= javascript_pack_tag 'application' %>
- 上記作業でDELETEリクエストを送信できなくなる(削除ができなくなる)ので,
rails-ujs
を追加します。コンソール$ yarn add rails-ujsapp/javascript/packs/application.js+ require("rails-ujs").start() require("trix") require("@rails/actiontext")
- リッチテキストエディタ導入のため,ビューなどの編集をします
config/routes.rbRails.application.routes.draw do root 'posts#index' # 追加 resources :posts endapp/models/posts.rbclass Article < ApplicationRecord has_rich_text :content # 追加 endapp/controllers/posts_controller.rbclass PostsController < ApplicationController private (略) def post_params params.require(:post).permit(:title, :content) # :contentを追加 end endapp/views/posts/_form.html.erb<div class="field"> <%= form.label :title %> <%= form.text_field :title %> </div> <!-- 以下を追加 --> <div class="field"> <%= form.label :content %> <%= form.rich_text_area :content %> </div> <!-- ここまで --> <div class="actions"> <%= form.submit %> </div> <% end %>app/views/posts/index.html<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <!-- 以下を追加 --> <tr> <td colspan="4"><%= post.content %></td> </tr> <!-- ここまで --> <% end %> </tbody> </table>app/views/posts/show.html<p> <strong>Title:</strong> <%= @post.title %> <%= @post.content %> # 追加 </p>
http://localhost:3000/posts/new
にアクセスすると……こんな感じの投稿ができます。もちろん投稿一覧にも反映されます!
3. Herokuにデプロイする際の注意点
基本手順は以前の記事などを参照下さい。
画像ファイルは時間経過やデプロイした際に消去されてしまうので,S3などを使用する必要があります。
Herokuにデプロイする際,Rails 6.0.0の不具合なのか次のエラーが発生します。
エラー内容(略) remote: rake aborted! remote: ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit` (略) remote: ! remote: ! Precompiling assets failed. remote: ! (略)次のコマンドで,Herokuに環境変数をあらかじめ追加することでデプロイできるようになります。
コンソール$ heroku config:set SECRET_KEY_BASE=`ruby -rsecurerandom -e "puts SecureRandom.hex(64)"`ところがもう一つ問題が……
jsやcssが404エラーとなり反映されない不具合が出ています。この問題は伊藤さんの記事に書かれているように,Herokuへの環境変数追加で解消できます。
コンソール$ heroku config:set RAILS_SERVE_STATIC_FILES=1
- 投稿日:2019-08-20T12:34:41+09:00
Rails6 のちょい足しな新機能を試す67(text size 編)
はじめに
Rails 6 に追加されそうな新機能を試す第67段。 今回は、
text size
編です。
Rails 6 では、 ActiveRecord のマイグレーションファイルのtext
に:size
オプションを指定できるようになりました。Ruby 2.6.3, Rails 6.0.0.rc1, MySQL 8.0.16, PostgreSQL 10.7 で確認しました。Rails 6.0.0.rc1 は
gem install rails --prerelease
でインストールできます。(Rails 6.0.0 がリリースされましたが、 確認当時は、 Rails 6.0.0.rc1 が最新でした。悪しからず
)
$ rails --version Rails 6.0.0.rc1なんとなく手抜きで、 モデルを1つ作って確認してみます。
プロジェクトを作る
rails new rails6_0_0rc1 cd rails6_0_0rc1
model を作る
User モデルを作ります。
bin/rails g model User nameマイグレーションファイルを編集する
users テーブルの マイグレーションファイルに text 型のカラムを追加します。
db/migrate/20190726231951_create_users.rbclass CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.string :name t.text :profile0 t.text :profile1, limit: 255 t.text :profile2, limit: 16777215 t.text :profile3, limit: 4294967295 t.text :profile4, size: :tiny t.text :profile5, size: :medium t.text :profile6, size: :long t.timestamps end end endMySQLを使ってマイグレーションを実行する
データベースに MySQLを使い、マイグレーションを実行します。
$ bin/rails db:create db:migrate
schema.rb を確認する
schema.rb では、以下のようになります。
db/schema.rbcreate_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t| t.string "name" t.text "profile0" t.text "profile1", size: :tiny t.text "profile2", size: :medium t.text "profile3", size: :long t.text "profile4", size: :tiny t.text "profile5", size: :medium t.text "profile6", size: :long t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false endmysql で確認する
mysql
で確認すると以下のようになっていました。mysql> show create table users\G *************************** 1. row *************************** Table: users Create Table: CREATE TABLE `users` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `profile0` text, `profile1` tinytext, `profile2` mediumtext, `profile3` longtext, `profile4` tinytext, `profile5` mediumtext, `profile6` longtext, `created_at` datetime(6) NOT NULL, `updated_at` datetime(6) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |PostgreSQL では
limit: 4294967295
を指定するとエラーになります。ArgumentError: No text type has byte size 4294967295. The limit on text can be at most 1GB - 1byte.ということで、以下のように修正して
db/migrate/20190726231951_create_users.rbclass CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.string :name t.text :profile0 t.text :profile1, limit: 255 t.text :profile2, limit: 16777215 t.text :profile3 # , limit: 4294967295 t.text :profile4, size: :tiny t.text :profile5, size: :medium t.text :profile6, size: :long t.timestamps end end end試してみると
schema.rb
は以下のようになります。db/schema.rb... create_table "users", force: :cascade do |t| t.string "name" t.text "profile0" t.text "profile1" t.text "profile2" t.text "profile3" t.text "profile4" t.text "profile5" t.text "profile6" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end ...試したソース
試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try067_text_size参考情報
- 投稿日:2019-08-20T08:02:36+09:00
初めてRails のサイトを Heroku でホスティングするときに躓いた,Precompiling assets failed. とrails credentials:edit
何があったか
RailsでHelloWorldを表示するサイトを作って,Herokuでホスティングしたい
git push heroku masterをすると,
$ Precompiling assets failed.が出てくる.
結論
エラーの本体
ArgumentError: Missing `secret_key_base` for 'production'environment, set this string with `rails credentials:edit`Precompiling assets failed. はエラーの本体ではない?
参考:Herokuにpushしたらprecompile assets faild.が。pushできたと思ったらApplication Errorが。解決するまで。- Qiita対処法
以下のコマンドを打つ
$ heroku config:set RAILS_MASTER_KEY=<your-master-key>your-master-keyはconfig\master.keyに書かれている文字列
例
$ heroku config:set RAILS_MASTER_KEY=123456789参考:Rails 5.2 with master.key - Heroku deployment - stackoverflow
何故このエラーが生じるのか
復号鍵を渡さないといけない?
詳細は以下に詳しく書かれてます.
参考:Rails 5.2 で ActiveSupport::MessageEncryptor::InvalidMessage - Qiita最後に
最初,Precompiling assets failed.で調べてたので,かなり時間をとってしまった.
ログはちゃんと見るべきその他参考にしたところ
https://railstutorial.jp/chapters/beginning?version=5.1#sec-exercises_hello_world
https://qiita.com/fuku_tech/items/b21e49ff49cb19f04838
https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39
- 投稿日:2019-08-20T08:02:36+09:00
初めてRails のサイトを Heroku でホスティングするときに躓いたPrecompiling assets failed. とrails credentials:edit
何があったか
RailsでHelloWorldを表示するサイトを作って,Herokuでホスティングしたい
git push heroku masterをすると,
$ Precompiling assets failed.が出てくる.
結論
エラーの本体
ArgumentError: Missing `secret_key_base` for 'production'environment, set this string with `rails credentials:edit`Precompiling assets failed. はエラーの本体ではない?
参考:Herokuにpushしたらprecompile assets faild.が。pushできたと思ったらApplication Errorが。解決するまで。- Qiita対処法
以下のコマンドを打つ
$ heroku config:set RAILS_MASTER_KEY=<your-master-key>your-master-keyはconfig\master.keyに書かれている文字列
例
$ heroku config:set RAILS_MASTER_KEY=123456789参考:Rails 5.2 with master.key - Heroku deployment - stackoverflow
何故このエラーが生じるのか
復号鍵を渡さないといけない?
詳細は以下に詳しく書かれてます.
参考:Rails 5.2 で ActiveSupport::MessageEncryptor::InvalidMessage - Qiita最後に
最初,Precompiling assets failed.で調べてたので,かなり時間をとってしまった.
ログはちゃんと見るべきその他参考にしたところ
https://railstutorial.jp/chapters/beginning?version=5.1#sec-exercises_hello_world
https://qiita.com/fuku_tech/items/b21e49ff49cb19f04838
https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39