ラベル Ruby on Rails の投稿を表示しています。 すべての投稿を表示
ラベル Ruby on Rails の投稿を表示しています。 すべての投稿を表示

2020年5月8日金曜日

ActiveJobの処理でファイルを添付していると performed_jobs が想定より1件多くなる?(Ruby on Rails, Minitest, ActiveStorage)

遭遇した現象

こちらを参考に、Jobが1件実行されたことを確認するテストを書いてみました。
https://api.rubyonrails.org/classes/ActiveJob/TestHelper.html#method-i-assert_performed_jobs

# download_job_test.rb

require "test_helper"

class DownloadJobTest < ActiveJob::TestCase
  setup do
    @my_image = my_images(:one)
  end

  # (省略)

  test "perform download job" do
    assert_performed_jobs 0
    perform_enqueued_jobs  do
      DownloadJob.perform_later(@my_image.id)
    end
    # Jobが1件実行されたことを確認する
    assert_performed_jobs 1
  end
end

ところが実行してみると、何故か2件のJobが実行されてFailします。

2020年2月1日土曜日

URI.encode が obsolete だそうなので WEBrick::HTTPUtils.escape に書き換えた

日本語を含むURI文字列をエンコードするために URI.encode を使っていたのですが、Rubocopさんに URI.encode は obsolete だと怒られたので書き換えたい。

W: Lint/UriEscapeUnescape: URI.escape method is obsolete and should not be used. Instead, use CGI.escape, URI.encode_www_form or URI.encode_www_form_component depending on your specific use case.
      encoded_uri = URI.escape(str)
                    ^^^^^^^^^^^^^^^

解決策

これでうまくいった!

irb(main):023:0> require 'webrick/httputils'
=> true
irb(main):024:0> WEBrick::HTTPUtils.escape(str)
=> "http://sample.com/My_Directory/2020/01/20200131_%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97.jpeg"

【参考】 URI.encode (Ruby 2.5.0 リファレンスマニュアル)

2019年12月27日金曜日

Rails 6.0にアップデートすると ArgumentError: Invalid formats: "json" エラーが発生するようになった

発生したエラー

Rails 5.2.3 → 6.0.2にアップデート後、テストを実行すると下記のエラーが発生

ArgumentError: Invalid formats: "json"

Controllerで下記の記述をしている箇所で発生している

render "index", formats: "json", handlers: "jbuilder"

解決策

Rails ガイドの レイアウトとレンダリング > 2.2.12.5 :formatsオプション を参照すると、以下のような例が記載されている

render formats: :xml
render formats: [:json, :xml]

2019年12月17日火曜日

fixture_file_upload を使うと他のテストがエラーになる

遭遇した現象

ActiveStorageを使っているプロジェクトで、fixture_file_upload を含むテストを追加したら、
関係ないはずの他のテストがランダムに失敗するようになった。

追加したのはこんな感じのテスト。

      test "create with valid file attachment" do
        image_file = fixture_file_upload("test/fixtures/files/sample.jpg", "image/jpg", :binary)
        post somethings_path, params: { something: { name:  "新規作成",
                                                     image: image_file } }
        assert_response :created
      end

失敗時のエラー

NoMethodError: undefined method `column_types' for nil:NilClass
  • 常にではない。成功するときもある。
  • fixture_file_upload を含むテストをコメントアウトすると、常に成功するようになる。
    コメントアウトを戻すとまたランダムに失敗する。
  • ActiveStorageの代わりにCarrierWaveを使っているプロジェクトでは、発生したことがない。(Railsのバージョンは同じ)
  • content_type をチェックするようなバリデーションがあるので、そこで失敗していそう。

2019年10月1日火曜日

Ransackを使用したソートのデフォルトの表示順を変更する

Ransack のREADMEにあるこの方法は、ソートのリンクをクリックした際に昇順・降順どちらから始めるかを指定するだけで、クリックする前の表示順は変えてくれない。

<%= sort_link(@q, :name, 'Last Name', default_order: :desc) %>

ソートが未選択の場合の表示順を変更したい場合、コントローラーで指定する。

Sorting in the Controller · activerecord-hackery/ransack Wiki
https://github.com/activerecord-hackery/ransack/wiki/Sorting-in-the-Controller

上記のWikiでは @search となっていますが、現在のREADMEの例に合わせて @q を使うとこんな感じ。

@q = Post.ransack(params[:q])
@q.sorts = 'name asc' if @q.sorts.empty? # ソートが未選択の場合はnameの昇順で表示
@posts = @q.result.paginate(page: params[:page], per_page: 20)

2019年8月17日土曜日

recent メソッドが見つからない…?(Ruby on Rails 5 速習実践ガイド)

Ruby on Rails 5 速習実践ガイドで躓いたところ。

Chapter 7-2で、本の記述に従って下記を tasks_controller に追加したところ、

@tasks = @q.result(distinct: true).recent

index を開こうとするとエラーが発生。

NoMethodError in TasksController#index
undefined method `recent' for #<Task::ActiveRecord_AssociationRelation:0x00007f8298add2d0> Did you mean? reject reset

調べてみたところ、この .recent は Ruby や Rails、または ransack gem で用意されているメソッドではない様子。

「rails .recent メソッド」で検索して下記ページに行き当たり、これはScopeなのでは?と思い当る。

Railsでよく利用する、Scopeの使い方。 - Qiita
https://qiita.com/ngron/items/14a39ce62c9d30bf3ac3

本の索引からScopeのページを探して見返すと、P. 178 に下記の記載が。

  scope :recent, -> { order(created_at: :desc) }

このページを読んだ時点では「たとえば次のように ... 使うことができます」としていくつか使い方の例が挙げられているだけだったので、この scope が後々必要になるとは思わず、追加していなかったことが原因でした。

app/models/task.rb にこの scope を追加すると期待通り動作するようになりました。


参考・引用元: 現場で使える Ruby on Rails 5速習実践ガイド | マイナビブックス

2019年7月30日火曜日

本番環境のデータをローカルのDBに投入したら UnknownMigrationVersionError と ProtectedEnvironmentError (Rails 5)

heroku上のアプリ からダウンロードしたデータをローカル(development)のDBに投入したところ、migration のバージョンが heroku上にあった物になってしまい、かつ、環境がプロダクションと認識されるようになってしまいました。

$ bin/rails db:rollback
rails aborted!
ActiveRecord::UnknownMigrationVersionError:

No migration with version number 201906********.

bin/rails:4:in `<main>'
Tasks: TOP => db:rollback
(See full trace by running task with --trace)

調べてみた所、migrationのバージョンの履歴は schema_migrations というテーブルに格納されていることが分かりました。

2019年7月28日日曜日

マイグレーションの現在のバージョンを調べるコマンド(Rails)

bin/rails db:version

入門書等で「バージョンを一つ前に戻す」や「特定のバージョンまで実行」などのコマンドは書いてあるのに今のバージョンを調べるコマンドが意外と書いてないことが多くて、毎回調べてるので。

参考: rake db:migrate - リファレンス - - Railsドキュメント

2019年7月6日土曜日

なんとかWSLで System Spec (System Test) 実行できた (Ruby on Rails 5)

2020/08/21 追記:最初に記事を書いた時とは別のPCで、VcXsrvなしで実行できることを確認しました。(インストールもしていない状態)
環境は以下の通りです。
Windows 10 Home バージョン1909
Ubuntu 18.04.5 LTS (Windows Subsystem for Linux)
Ruby 2.6.5
Rails 6.0.2.2

Minitestでのみ確認しました。RSpecは最近触っておらず…。

2019/08/31追記:結局現在は、VcXsrvもgoogle-chromeも起動させていなくても実行できるようになっています…いつの間にか。
何が影響したのかは分からず…。Windows Updateはありました。(Windows 10 Home, 現在のバージョンは1903)
Ubuntu, Ruby, Rails のバージョンは変わっていません。

2019/07/08訂正:何度もすみません。勘違いがありましたので再度訂正します。

一度VcXsrvは不要と書いたのですが、Headless Chromeを使用する場合でもやはり起動だけはさせておかないといけないようです…。
また、削除しても動いたと思っていた require 'capybara/rspec' require 'webdrivers' の二行が必要でした。
最初に記事を書いた時点からの変更点は以下となります。

  • spec_helper.rb の記載内容
    require 'capybara/rspec' require 'webdrivers' を追加
  • WSLで google-chrome を叩いて、Chromeを起動だけしておく
    → ここで google-chrome --headless --disable-gpu --no-sandbox とすれば
    Errorが出なくなりました。


「Ruby on Rails 5 速習実践ガイド」を見ながらRSpecのテストを実行しようとして詰まりました。
3日くらい試行錯誤してなんとか実行まで漕ぎつけたのでその方法のメモです。

途中から心が折れて解消した手順とかエラーメッセージとか正確に控えてません…ごめんなさい。

また、Minitestのみ使っている別のプロジェクトでSystemTestを実行する方法も並行して調べていたので、情報が混ざっていたらすみません。Capybaraを動かす方法という意味では同じだと思うのですが。

少しでも参考になれば幸いです。

2019年6月26日水曜日

carrierwave のnilチェック

「ファイルが添付されていないこと」をチェックしたいときは .nil? ではなく .file.nil?

参考:carrierwaveuploader/carrierwave: Classier solution for file uploads for Rails, Sinatra and other Ruby web frameworks
https://github.com/carrierwaveuploader/carrierwave#activerecord

Note: u.avatar will never return nil, even if there is no photo associated to it. To check if a photo was saved to the model, use u.avatar.file.nil? instead.

Userモデルのavatarカラムにcarrierwaveのuploaderをマウントしている場合、 u.avatar.nil? は(たとえファイルが添付されていなくても)nilにはならない。

2019年3月11日月曜日

Devise に omniauth-google-oauth2 でGoogle認証を追加する (Rails 5.2.2)

Rails 5系の情報がまだあまり無いようだったので。とりあえずうまくいった手順です。

結論

こちらを参考にGoogle Developers Console側の登録をした後、
爆速ッ!! gem omniauth-google-oauth2 で認証させる - Qiita

Railsアプリ側の設定は、omniauth-google-oauth2のREADMEに「Devise」の項があるので、それに従ってやればうまくいきました。
zquestz/omniauth-google-oauth2: Oauth2 strategy for Google > Devise

前提条件とやりたいこと

今回は以下を目指します。

  • 既にDeviseでUserというモデルを作成済みの所にGoogle認証機能を追加する
  • 既にそのメールアドレスで登録があればログイン、無ければGoogleからメールアドレスと名前を引っ張ってきて自動で新規登録する

背景として、とある会社のGSuiteアカウントでしかログインできない社内向けツールを作るために調べた情報です。
おそらくGSuiteに限らずログイン可なアプリを作る場合でもそんなに変わらないはず。

2018年11月17日土曜日

My first PR was merged into dev.to!

My first PR to an open source project was successfully merged. The repo it got merged into was dev.to!

Add GitLab URL field to user profile by sidemt · Pull Request #1121 · thepracticaldev/dev.to

Feature I added

I added a new field to put a link to GitLab profile on DEV profile.

@ben gave me a comment on GitHub so I wrote the changelog post for it too.

Changelog: Add GitLab link to your profile - DEV Community

My thoughts

As many of you may know dev.to uses Ruby on Rails. I have learned the basics of Rails and have made a few web apps as personal projects but had never worked on such a large project.
But there already were similar URL fields and one of them was added recently so I could easily find out what I needed to change by looking into the PRs and codes of the other fields.

The most difficult part for me was setting up the environment locally.

Ruby on Rails on Windows

I'm a Windows user.

As far as I know, I can't install rbenv on Windows. So I used WSL(Windows Subsystem for Linux).

  • The environment of Ruby (on Rails) is installed on WSL(Ubuntu)
  • PostgreSQL is installed on Windows
  • The code cloned from the dev.to repo is stored on Windows

There is a detailed guide in dev.to's documentation. It helped me a lot.

Where I got stuck

I'm thinking of writing detailed posts on how I resolved these troubles later.

  • Initial installation before I can launch dev.to locally
  • Couldn't sign-in on the local environment (Thanks @andy for the help on this!)
  • Sign-in started working, but instead, Rubocop had an error of Ruby version mismatch which prevented me from making a new commit (it's in the pre-commit hook)
  • It seemed something was wrong with the Ruby versions managed by rbenv but I couldn't resolve it. After investigating for a whole day I decided to reset the WSL and installed everything again (I could do this because dev.to was the only project I'm using WSL)

After going through these challenges, I finally submitted the PR.

What I learned

The code I added was 30 lines or so. 90% of my work was setting up the environment.

But as a code newbie who has no work experience as a developer, I learned a lot from this installation process.

When you create something by yourself you would use something you know or have heard of. Going through all the errors, I had many chances to deal with things I had no idea what they were.

Many "things I don't even know they exist" became "things I have heard of their name" and "things I kind of know what they do". I can now guess "I might be able to do this using this..." and search for it more easily.

If you are a beginner in programming, I recommend you trying to set up a development environment of a large open source project. Even if you can't eventually submit a PR, you can get an idea of what a real-world project looks like, you can practice reading the error message and searching for solutions, you can see the names of a huge number of modules which might help you in the (near) future.

Actually, I was considering to submit my first PR to freeCodeCamp at first (But I couldn't find "first timers welcome" issues available. I was lucky to find an entry-level issue here!) so I recently installed its environment too. These experience made me think that setting up a local environment of open source projects may be a good practice for beginners.

GitLab users!

I use GitLab for my private repositories. It's free!

If you are a GitLab user please try adding the link to GitLab on your DEV profile!

2018年11月16日金曜日

はじめてのぷるりく @ dev.to

初めてオープンソースのプロジェクトにPRを出してマージされました!嬉しい!!

Add GitLab URL field to user profile by sidemt · Pull Request #1121 · thepracticaldev/dev.to

DEV Community (dev.to) という、英語圏のMediumとQiitaの中間みたいな感じのサービスの機能追加にコントリビュートしました。

DEV Community (https://dev.to/)

日本のTwitterでも話題になったことがあるようで、時々名前を見かけるので結構知られているのかなと。
(周りにエンジニア系のリアル知り合いがいない初心者なものでその辺の温度感が分かりません…)

追加した機能

dev.toのプロフィールにGitLabのプロフィールへのリンクを追加できるようにしました。

Changelogの投稿もして良いですよとコメントいただいたので簡単にですが投稿させていただきました。

Changelog: Add GitLab link to your profile - DEV Community

所感

Ruby on Railsのプロジェクトです。
こんな大規模なプロジェクトのコードに変更を加えるのは初めてだったのですが、同様の入力欄がすでに多数あり、最近も追加されていたので、その時の変更内容や他の欄のコードを参考にして書くことができてそんなに難しくありませんでした。

難しかったのは環境構築でした。

WindowsでRuby on Rails

まずWindowsユーザーなのですが、たぶんRails(Ruby)をやるには向いてないんですよね。Windows。今回すごい実感して今後の方向性考えたほうがいいのかなと思いました(笑)

今回WSL(Windows Subsystem for Linux)を使って、

  • Ruby・Rails周りの環境はWSL(Ubuntu)にインストール
  • PostgreSQLはWindows側にインストール
  • dev.toのリポジトリからクローンしたコードはWindows側に置く

という形にしました。dev.to公式のドキュメントでこの方法も書いてあって助かりました。

躓いた点

このあたりの詳しい躓きポイントと解決した方法は別途記事にできたらいいなと思ってます。

  • まずローカルで起動できるようにするまでに躓く
  • 起動できたと思ったらサインインできなくて躓く
  • サインインできて動作チェックして直して、修正をコミットしようとしたらコミット時に自動で走るRubocopでエラーが出るようになっててコミットできなくて躓く
  • rbenv のバージョンがおかしなことになってるのは分かったけれど1日やって直せなくて結局WSLをリセットしてインストールしなおす(このプロジェクトしかやってなかったからできる解決策)

→で、ようやくPR出せました。

オープンソースプロジェクトの環境構築で初心者が学べること

追加したコードは数十行で、作業時間の9割くらいは環境構築を試行錯誤していたのですが(笑) 実務経験の無い初心者としてはこのおかげで学ぶものが大きかったです。

自分一人で何か作っても、自分が全く知らないものを無理やりにでも触って動かすという経験はなかなかできないので。

例えば実際にPRを出すところまでまだ行けなくても、大規模なオープンソースプロジェクトの開発環境をローカルに構築して起動するようにしてみるだけでも、「実務の世界で使われているようなコードはこんな規模なんだ(きっと)」と感じることができ、エラーメッセージから解決策を調べる練習にもなり、いろんなモジュールの名前を目にすることもでき。学べたことが多々ありました。

存在すらしらない→名前だけは見たことがある→どういう系の機能で使われるものかなんとなく分かる、という状態にできると、自分が「こんなことを実現したい」と思ったときに格段に調べやすくなると思っているので、オススメです。

実は最初初めてPRを出すリポジトリは freeCodeCamp にしようと思ってそちらの環境構築もしていたので、比較的短期間に異なる言語・フレームワークのプロジェクトの環境構築を2回やって、そんなことを感じました。


dev.toお使いの方、ぜひGitLabのURL追加してみてください!

2018年9月13日木曜日

RuboCop さんと付き合う (Style/GuardClause, Layout/IndentationConsistency)

Rails Tutorial を参考にしながら書いた下記のコードで RuboCop さんに指摘されたところに対処していきます。
指摘は2つ。

  • Style/GuardClause: Use a guard clause instead of wrapping the code inside a conditional expression.
  • Layout/IndentationConsistency: Inconsistent indentation detected.

class StaticPagesController < ApplicationController
  before_action :logged_in_user, only: [:my_page]

  def home
    ...
  end

  def my_page
    ...
  end

  private

    # before action
    def logged_in_user
     unless user_signed_in?
       flash[:danger] = 'Please log in.'
       redirect_to root_url
     end
    end
end

2018年9月11日火曜日

Devise を導入すると ActiveRecord::RecordNotUnique: エラーでテストが動かなくなったので対処(暫定対応)

Rails Tutorial のサンプルアプリをベースに作り始めたアプリに、 Devise によるユーザー登録を追加したところ、全てのテストで下記のエラーが出るようになりました。
テストには Minitest を使用しています。

ActiveRecord::RecordNotUnique:         ActiveRecord::RecordNotUnique: SQLite3::ConstraintException: UNIQUE constraint failed: users.email: INSERT INTO "users" (...

emailの重複制約に引っかかっている様子…?

テスト環境のユーザーはどこに設定があるんだっけと思い返したところ、 test/fixtures/users.yml の内容がデフォルトで下記のようになっているのを発見。


one: {}
# column: value
#
two: {}
# column: value

おそらくこれのせいで、同じ値を使って one と two の二人のユーザーが作られる状態になっているのかと。
two を削除すると、とりあえずまたテストが動くようになりました。


one: {}
# column: value

この後ユーザーが絡んだテストを追加する際にちゃんとした対応が必要そうですが…取り急ぎ。

2018年8月28日火曜日

ブラウザのキャッシュクリア機能をテストするサイト作りました

Clear Cache Test

わざと画像をキャッシュするサイトです。
「Edit」から違う画像を投稿しても、ブラウザのキャッシュをクリアするまで新しい画像が表示されません。

2018年8月27日月曜日

Ruby on Rails で "Uncaught ReferenceError: $ is not defined" エラー

Ruby on Rails のプロジェクトで jQuery が動かなくて、開発者ツールを見たら下記のエラー。

Uncaught ReferenceError: $ is not defined

app/assets/javascripts/application.js に下記が抜けてました。


//= require jquery
//= require jquery_ujs

下記ページを参考にして、 //= require_tree . より上に追加。
Uncaught ReferenceError: $ is not defined【rails】 - Qiita

こんな感じで。


//= require rails-ujs
//= require turbolinks
//= require jquery
//= require jquery_ujs
//= require_tree .

2018年8月26日日曜日

Railsで作ったEditフォームのエラー時に再読み込みするとRouting Errorになる

Rails Tutorialのサンプルに変更を加えながらウェブアプリを作っているのですが、
Edit フォームで、 validation エラーが出た画面で再読み込みするとエラーが出てしまう問題に遭遇。

(Web経由では) edit と update しかさせないというちょっと変な仕様にしようとしてるので、そのせいかなとも思うのですが。(Userとも紐づけてないし)

でも1年くらい前に同じチュートリアルをやっていた時も同じ現象があって解決したような気がして(その時はサンプル通りに作っていたはず)
でもその解決方法が思い出せないので、今回やった方法を覚え書き。
正しい解決策かは自信が無いですが…

状況

↓問題が起きていたコード

2018年8月24日金曜日

assert_select について覚え書き(Ruby on Rails, Minitest)

assert_select を使ったテストについてメモ。


<div class="container">
  <ul>
    <% if logged_in? %>
      <li id="user_info">Logged in as: <%= current_user.email %></li> <!-- これが表示されている/いないをテストしたい -->
      <li><%= link_to "Log out", logout_path, method: :delete %></li>
    <% else %>
      <li><%= link_to "Log in", login_path %></li>
    <% end %>
  </ul>
</div>

「表示されている」かつ「文言が正しい」ことは、これでテストできた。


assert_select "li#user_info", "Logged in as: " + @user.email

「表示されていない」は、これだとうまくいかない


assert_select "li#user_info", "Logged in as: " + @user.email, count: 0

Expect 0 to be >=1 だったかな?1個以上あることが期待値とされてしまう。
二つ目の引数 "Logged in as: " + @user.email, を条件の感覚で書いていたけど、おそらく期待値となるメッセージとして扱われてて、最後の count: 0 が使われてない。

これでうまくいった。


assert_select "li#user_info", count: 0

id="user_info"<li> 要素自体が0個であることを確認する感じ。

参考: Rails テスティングガイド | Rails ガイド

2018年8月23日木曜日

Ruby on Rails (のERB) で {} が表示されるときの確認ポイント

Ruby on Rails のコードを触っていてふと気づいたら謎の波括弧 {} がページ上に表示されるようになってました。

Ruby のコードを <% ... %> で囲うべきところを <%= ... %> にしてしまっていたのが原因でした。

解決。

参考: Ruby on Rails チュートリアル:実例を使って Rails を学ぼう
3.4.3 レイアウトと埋め込みRuby (Refactor)