20201011のRubyに関する記事は30件です。

アプリの作成とherokuで初めてのデプロイ

アプリケーションの作成

rails new railsgirls
cd rails server

scaffoldを使って、idea,add,remove,edit,viewを形成します。
rails generate scaffold idea name:string description:text picture:string

次に、データベースの更新をします。
rails db:migrate

デザイン

Bootstrapを使って、デザインをします。

app/views/layouts/application.html.erb
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>

この1行前に次を追記

app/views/layouts/application.html.erb
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">

また、次のように<body>内を修正します。

app/views/layouts/application.html.erb
<div class="container">
  <%= yield %>
</div>

次に、ナビゲーションとフッターをレイアウトに追加します。<body>の直後に以下を追加します。

app/views/layouts/application.html.erb
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="/">The Idea app</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="/ideas">Ideas</a></li>
      </ul>
    </div>
  </div>
</nav>

さらに、</body>の直前に以下を追加します。

app/views/layouts/application.html.erb
<footer>
  <div class="container">
    Rails Girls 2020
  </div>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

さらに、ideasの表のスタイルも変更します。

app/assets/stylesheets/application.css
body { padding-top: 100px; }
footer { margin-top: 100px; }
table, td, th { vertical-align: middle; border: none; }
th { border-bottom: 1px solid #DDD; }

写真のアップロード機能の追加

Gemfileを開いて、
gem 'sqlite3' の直後に、次の1行を追加します、
gem 'carrierwave'

次に、ターミナルで以下のコマンドを実行します。

bundle

そうすると、次のコマンドでアップロードを実行するコードを生成できます。

rails generate uploader Picture

次に、

app/models/idea.rb
class Idea < ApplicationRecord

の直後に、以下を記述します。

app/models/idea.tb
mount_uploader :picture, PictureUploader

さらに、

app/views/ideas/_form.html.erb
<%= form.text_field :picture %>

これを、以下のように修正します。

app/views/ideas/_form.html.erb
<%= form.file_field :picture %>

これでは、ファイルのpathを表示しているだけです。
なので、

app/views/ideas/show.html.erb
<%= @idea.picture %>

上記のコードを以下のように修正します。

app/views/ideas/show.html.erb
<%= image_tag(@idea.picture_url, width: 600) if @idea.picture.present? %>

rootの調整

http://localhost:3000でideasページにリダイレクトできるようにします。

config/routes.rb
root to: redirect('/ideas')

アプリにページを追加する

rails generate controller pages info

Herokuにアプリをアップロード

Herokuの準備

まずは、Herokuのアカウントを準備します。
ユーザ登録画面: (https://signup.heroku.com/)

Heroku CLIのインストール

Herokuでコマンドライン操作を行うためのアプリケーションをダウンロードします。

Macの場合
brew install heroku/brew/heroku

Heroku Toolbeltがインストールできたら,ターミナルに次のコマンドを入力します。
heroku login

次に、作成したコードをバージョン管理システムに追加します。
ターミナルで次のコマンドを入力します。

echo public/uploads >> .gitignore
git add .
git commit -m "initial commit"

データベースのアップデート

gem 'sqlite3', '~> 1.4'

このコードを以下のように修正します。

group :development do
  gem 'sqlite3', '~> 1.4'
end
group :production do
  gem 'pg'
end

そして、ターミナル上で次のコマンドを実行して、セットアップする。

bundle install --without production
git add .
git commit -m "Added pg gem and updated Gemfile.lock"

アプリのデプロイ

Herokuのアプリを作ります。
アプリの名前は、heroku上でユニークな名前じゃなければダメです。
heroku create first-app

成功したら次のように表示されます。
Creating ⬢ first-app... done
http://my-first-app.herokuapp.com/ | https://git.heroku.com/my-first-app.git

もし、アプリの名前が既に使われてたら、以下のように表示されます。
Creating ⬢ my-first-app... !
▸ Name first-app is already taken

コードをpush
herokuにコードを送信します。
git push heroku main

データベースのマイグレート
heroku run rails db:migrate

次のコマンドを実行したら、インターネットからアプリを見ることができます。
herku open

参考

Rails Girls Guides
https://railsgirls.jp/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

getsとgets.chompの違いについて(改行以外)

インターネットに掲載されているドリル問題を解いていたときにrubyのgetsgets.chompの違いについて新たな発見があったためアウトプットして行きます!

結論

改行は1文字に含まれる!
は?っ思った方もいらっしゃるでしょう。私にとっては新たな発見だったのです...。
以下のコードを例にみてみます。

ruby.rb
str = gets
puts str.length

getsメソッドを使用しているためターミナルが入力待ちの状態になります。
そこで'abc'と入力すると4と出力されます。
てっきり3が返ってくると思っていた私は「なぜ!!????」とプチパニック状態に笑
もしかしてと思いgets.chompで同じことを行うと予想通り3と返ってきました。

最後に

今まではchompをつけることで改行しないんだよな〜くらいの認識でしかありませんでした。
返り値が変わってくるというのは新たな発見でした。
lengthメソッドでは改行だけではなく空白も1文字としてカウントされますが、なかなかその感覚に慣れておらず、変な感じがしてしまいます。これは慣れなのでしょうかね?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【日本語版Faker】「gimei」というGemについて

背景・プロフィール

未経験から自社開発系企業の就職を目指しています。

知識レベルとしては、Ruby on railsを使って簡単なアプリケーション開発、gitを使ったバージョン管理、herokuを使ってデプロイできるレベルです。
現在は主にRuby on rails、javascript、Docker、AWS、CircleCIあたりについて学んでいます。

今回のお題に関して

今回は 「gimei」というRuby on Railsで使えるGemについて書きたいと思います。
「gimei」はテストコードを書く際など、ランダムな日本語データを生成するときに使えるgemです。

Fakerの文字列生成方法を検索しているときにに偶然見つけました。非常に便利だと思ったので紹介します。(※それと自分の忘備録のためです。)

「gimei」とは・・・

「gimei」はランダムな日本語のデータを作成してくれます。例えば架空の日本人の名前や地名などです。

railsでテストコード書いたことある人は「faker」というgemを使ったことがあると思いますが、簡単にいうと「gimei」は日本語に特化したFakerです。「faker」はランダムな文字(主に英語)を生成する一番有名なGemですが、実は日本語のフリガナには対応していません。そのため「faker」だけで文字列を生成しようとすると、日本語の名前や住所で登録するアプリケーションのテストコードを書く際に少し不便です。「gimei」のGemはそんな悩みを解決してくれます。

【gimeiの公式github】gimei/公式

「gimei」の使い方について

gimeiの公式を見ていただければ日本語で説明書いてあるので、ほとんど解説不要かと思いますが一応書きます。
まずはGemfileに記述しましょう。

Gemfile
group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 4.0.0'
  gem 'factory_bot_rails'
  gem 'faker'
  gem 'gimei'
end

上記のように、おそらく「gimei」を使う際は、テストの際に「FactoryBot」と一緒に使うことが多いと思いますので、テストのグループの中にいれましょう。そしたらbundle installして準備完了です。あとはfactoriesファイルなどに記述するだけです。コンソールでランダムな日本語が生成することが確認できます。

console
user@user application % rails c
[1] pry(main)> Gimei.last.katakana 
=> "タケシタ"
[2] pry(main)> Gimei.first.katakana
=> "ハルト"
[3] pry(main)> Gimei.city.kanji
=> "稲敷郡阿見町"

こんな感じです。日本人の漢字の名前や地名も簡単に生成できるので、非常に便利です。「gimei」と「Faker」を組み合わせれば、ランダム文字の生成に関してはほとんど対応できます。日本語のアプリケーションを開発している方は是非使ってみてください。

感想・まとめ

個人的にですが英語があまり得意でなく、「faker」の公式githubですら読むのに一苦労しました。いずれかは英語の文献にも慣れないといけないですね。。。。
とはいえ「gimei」は日本語で説明書いてあるし、内容も簡単なので初学者でも簡単に取り入れることができます。ぜひ使ってみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails ログイン機能のバリデーション設定

Userモデルのname,emailカラムにバリデーションを設定

Railsガイドなどを参考にしています。
https://railsguides.jp/active_record_validations.html

【やりたいこと】
・名前やメールアドレスは空欄で登録できないようにする
・名前とメールアドレスの文字数制限

ポイントは
①"presence: true"→空欄での登録を禁止する
②"length: { maximum: }" → ":"の後ろに設定した数字以上の長さを禁止する

app/models/user.rb ファイルでの作業になります。
作成したのは下記のコード。

class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 20 }
  validates :email, presence: true, length: { maximum: 300 },
end

うまくいっているか、Rails consoleで確認してみる。まずは空欄で登録しようとすると。。。

> User.create(name: "", email: "")
   (0.3ms)  BEGIN
   (0.4ms)  ROLLBACK
 => #<User id: nil, name: "", email: "", created_at: nil, updated_at: nil>

ROLLBACKして登録されていません。

そして長い名前やメールアドレスを登録しようとしてみると、これもROLLBACKしていることが分かります(email欄の...となっている部分はあまりに長いので記事での表示を省略しています)。

> user = User.create(name: "a"*25 , email: "b"*350 + "@test.com")
>  (0.3ms)  BEGIN
>  (0.4ms)  ROLLBACK
=> #<User:
     id: nil,
     name: "aaaaaaaaaaaaaaaaaaaaaaaaa",
     email:"aaaaaaaaaaaaaaaaaaaaaaaaa...@test.com",
     created_at: nil,
     updated_at: nil>

エラーの理由を表示すると。。。

> user.errors.messages
> {:name=>["is too long (maximum is 20 characters)"],
 :email=>["is too long (maximum is 300 characters)"]}

"length: { maximum: }"がちゃんと機能していることが確認できました。

ちなみにmaximumとなっている部分は、いろいろ応用して使えるようです。
(下記Railsガイドより)

class Person < ApplicationRecord
  validates :name, length: { minimum: 2 }
  validates :bio, length: { maximum: 500 }
  validates :password, length: { in: 6..20 }
  validates :registration_number, length: { is: 6 }
end

:minimum: 属性はこの値より小さな値を取れません。
:maximum: 属性はこの値より大きな値を取れません。
:inまたは:within: 属性の長さは、与えられた区間以内でなければなりません。このオプションの値は範囲でなければなりません。
:is: 属性の長さは与えられた値と等しくなければなりません。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsでいいね順に投稿を並べる(ランキング)

概要

ネットでrailsのいいねランキングを探すとjoinを使った内部結合でいいねが1つ以上ある投稿をランキングする記事は見つかったがいいねが0のものを含めたランキングの記事が見つからず、
頑張って実装したので理解度を深める意味で殴り書きします。

前提

Questionモデル(投稿)
Likeモデル(いいね)

実装

※長くてごめんなさい

@questions= Question.left_outer_joins(:likes).group('questions.id').select('questions.*, COUNT(likes.*) AS likes_count').distinct.reorder(likes_count: :desc).limit(100)

解説…?

  1. Questionモデルにleft_outer_joins(:likes)でlikesテーブルを外部結合する
     joinsメソッドを使った内部結合だといいねされていないQuestionが除外されるため外部結合を使う。

  2. 1で結合したテーブルをquestions.idでグループ化する
      いいねされている対象のQuestionが同じ同士でグループ化する

  3. select文で返すデータを指定(questionテーブルの全てとlikes_count)

  4. distinctで重複したデータを取り除く。

  5. ここ重要! reorderメソッドでlikes_countが多い順に並べ替える
    orderメソッドだとQuestionsテーブルのデフォルトの並び順(新規登録順)が適用されてしまうため
    reorderメソッドで並び順を書き換える

6.(ここはお好みで)limitメソッドでデータの取得件数を100件に絞る

最後に

正直曖昧な理解が多くなんとかこぎつけた実装なので間違っていたり効率が悪いかもしれません。。
それとなく教えてくださると幸いです。。

この辺りのActiveRecordのクエリインターフェースに関してはRailsガイドがとてもわかりやすく載っているので
是非参考に

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

オブジェクト指向を自分なりにまとめてみた。

はじめに

はじめまして。大学生エンジニアのMackeyです。
今回は、今までよくわかんなかったオブジェクト指向について自分なりにクソ簡潔にまとめてみました。
また、今回題材となる言語はRubyです。
初Qiitaの記事なので、変なところなどはあると思いますが、そこはあしからず。

記事を読んでいただく上での前提

・rubyでは、全ての値がオブジェクトである
・オブジェクトはクラスから生成することができる
・オブジェクトは何らかのクラスに所属している
・変数の概念を理解している

参考URL

・キノコード / プログラミング学習動画のYouTuber さんの
【Ruby超入門コース】13.クラス|クラスとは、「データ」と「処理」をまとめたもの!【プログラミング初心者向け入門講座】
https://www.youtube.com/watch?v=E5IX_WLuvcs&list=PLavQwENTsEBUAgSok7Ww4-Q-ZHissbMOv&index=14

この方の説明はとてもわかりやすいので是非チャンネル登録してください。

そもそもオブジェクト指向とは何ぞや。

プログラミング初心者の方がプログラミングをやっていてぶつかる壁の一つとしてオブジェクトやクラスやインスタンス、メソッドなどといったことが挙げられると思います。なので初心者の方向けにそれぞれのワードを専門用語なしで説明していきたいと思います。

そもそもオブジェクト指向とは

クラスとは

クラスとは設計図や骨組みのイメージ。

インスタンスとは

インスタンスはオブジェクトの中でもクラスから生成された物を強調したいときに使う言葉。

メソッドとは

Class.rb
//studentクラスの生成
class Student

  //initializeメソッドはオブジェクトを生成したときに自動的に実行されるメソッド
  def initialize(student_name)
    @name = student_name
  end

  //数学と英語の平均点を表示するメソッド
  def average(math,english)
    result = (math + english) / 2
    p @name,result
  end

end

//オブジェクトを生成
a = Student.new("tanaka")

//studentクラスのインスタンスaでaverageメソッドを実行
a.average(50,30)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails でTimezoneを動的 に保存、表示する実装方針

背景と要件

Meetingなどのイベントの時間をあらゆるタイムゾーンを考慮して保存したいという要求がありました。

たとえば、
Meeting1 は Tokyo で 11:00 〜開催される。
Meeting2 は UTC で 10:00〜開催される。

のようなことを表現したい。

実装手順

  • RailsのAPIサーバーのdefaultのTimezoneを固定する。
  • DBにTimezoneを保存する
  • Timezoneを動的に変更するロジックをどこに挿入するかを決める。
  • timzoneを考慮して、DBにtime型が保存されるか確認
  • 保存する際に、timezone情報が無いstringが渡されないようにvalidation

RailsのAPIサーバーのdefaultのTimezoneを固定する。

まずRailsは考慮するタイムゾーンが複数存在します。

https://qiita.com/joker1007/items/2c277cca5bd50e4cce5e

今回は、混乱をさけるため一旦以下すべてのTimezoneをUTCにしました。

  • database
  • activereocord
  • system

DBにTimezoneを保存する

timezoneを変更する基準となる変数を保存します。
timezoneは ActiveSupport経由で変更するので、validな値が保存されるように以下のようなvalidationを書けます。

# tz :string
class Meeting < ApplicationRecord 

validates :tz, inclusion: { in: ActiveSupport::TimeZone::MAPPING.values }, presence: true

end

APIでGET時に、timezoneをdynamicに変更するロジックをどこに挿入するかを決める。

APIで値を返すときに、動的にTimezoneを変更して時間を返すロジックをいれます。
今回の場合はSerialzerにくみこみました。このロジックは表示に関わるロジックなので、結果的にViewに近いLayerでいれることになりました。

#  tz :string
class Meeting < ApplicationRecord 
  ~ 省略 ~

  def timezone
    ActiveSupport::TimeZone.new(tz)
  end

  def use_timezone
    Time.use_zone(timezone) do
      yield
    end
  end
end
class MeetingSerializer

  attribute :start_time do |record|
    record.use_timezone do
      record.start_time
    end
  end

end

timzoneを考慮して、DBにtime型が保存されるか確認

保存はtimezone情報がついている、stringを渡せば、ActiveRecordがいい感じにやってくれます。

# actieve_record のtimezone は UTC

[47] pry(main)> meeting
=> #<Meeting:0x00007ff2c7ad4618
 id: "162b1ed7-5502-42f8-8bed-592d2dae7db1",
 start_at: Mon, 05 Oct 2020 16:00:00 UTC +00:00,
 created_at: Tue, 06 Oct 2020 06:28:39 UTC +00:00,
 updated_at: Thu, 08 Oct 2020 02:11:54 UTC +00:00>
[48] pry(main)> meeting.start_at="2020-10-06T01:00:00+0900"
=> "2020-10-06T01:00:00+0900"
[49] pry(main)> meeting.start_at
=> Mon, 05 Oct 2020 16:00:00 UTC +00:00

保存する際に、timezone情報が無いstringが渡されないようにvalidation

以下のような、controllerのconcern moduleを作成し、before_action でvalidationをかませるようにしました。

module ValidateTimeFormat
  class TimeFormatError < StandardError
  end

  extend ActiveSupport::Concern

  included do
    rescue_from ValidateTimeFormat::TimeFormatError, with: :render_time_format_error
  end

  TIME_FORMAT = '%FT%T%z'

  def render_time_format_error(msg)
    render json: { message: msg }, status: :bad_request
  end

  def validate_time_format(time_str)
    DateTime.strptime(time_str, TIME_FORMAT).zone
  rescue Date::Error
    raise ValidateTimeFormat::TimeFormatError, :time_format_is_invalid
  end
end

まとめ

RailsはTime系は考慮するポイントが多いイメージがありました。
今回実装したことで、完璧に理解しました()

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[ Ruby ]クラスのネストや、継承、selfについて

はじめに

作業しながらも、継承の影響範囲ってどこまでだっけ。。とか
この場合のselfは何を指しているんだっけ。。とか
基礎部分をフワッとしか理解できていなかったので今回は

  • クラス
    • 継承
    • self
    • ネスト

といった内容を、実際に書きながら学んでいったのでその記録として書きます。
メソッドや変数のことも書きたいのですが、長くなりそうなので別で書きたいと思います。

クラスの継承

クラスを定義する際にスーパークラスを1つ指定することができ、
この時に指定しない場合は、自動的にobjectクラスを継承します。
そのため、クラスを新しく定義する時は常に何かのクラスを継承する形になり
必ず継承ツリーのどこかに入ることになります。

継承する対象

  • スーパークラスのクラスメソッド
  • インスタンスメソッド
  • メソッド内に記述されているインスタンス変数

また、継承ではありませんが、スーパークラスの定数、クラス変数も参照できます。

class Klass
  VALUE = "I'm VALUE"
  @@class_val = "I'm class_val"
end

class A < Klass
end

class B < A
  def self.display_bal
    puts @@class_val
  end
end

# スーパークラスの定数の参照
puts B::VALUE
# => I'm VALUE

# クラス変数の継承
B.display_val
# => I'm class_val

self

selfはオブジェクトそのものを指すので、使用する場所によって中身が変わります。

以下の例では、インスタンスメソッド内で使用した場合のみ、インスタンスオブジェクトを指しました。
また、クラスメソッドを定義する際に用いるselfは、クラスオブジェクトを指しているため
self.メソッド名selfを直接クラス名で指定することもできます。

class Klass
  # Klass
  p self

  # Klass
  def (p self).class_method
      puts "inner_class_method"  
      # Klass
      p self
  end

  def instance_method
    puts "inner_instance_method"
    # <Klass:0x00007fa07e1a47c8>
    p self
  end
end

Klass.class_method
klass_instanse =  Klass.new
klass_instanse.instance_method

クラスのネストなど

クラスを定義する際に、他のクラスにネストさせることができます。
定義の仕方として以下の2パターンがありますが、一部挙動が変わってきます。

# 直接中に記述する
class TopKlass
  class Klass
  end
end

## ------ ##

# ”::”を用いる
class TopKlass
end

class TopKlass::Klass
end

定義の仕方による挙動の違い

定数の参照

・直接中に記述
自身からトップレベル方向へ順に定数を参照していきます。
自身から近い順にから順に参照していき、最後にトップレベルを参照するという流れになります。

VALUE = "Top level"

class TopKlass
  VALUE = "in TopKlass"

  class InnerKlass
    def self.put_value
      puts VALUE
    end
  end

end

TopKlass::InnerKlass.put_value
# => in TopKlass

・ネームスペースを用いて記述
自身に定数がなければ、次にトップレベルを参照すし、そこから順に自身のクラス方向へ参照していきます。

VALUE = "Top level"

class TopKlass
  VALUE = "in TopKlass"
end

class TopKlass::InnerKlass
  def self.put_value
    puts VALUE
  end
end

TopKlass::InnerKlass.put_value
# => Top level

class,module のどちらにネストさせるのかを明確にする

・中に記述
各階層でclassかmoduleかを指定するため、別で定義したmoduleをclassとして指定するとエラーになります。

module TopKlass
end

class TopKlass
  class InnerKlass
  end
end

# => TopKlass is not a class (TypeError)

・ネームスペースを用いて記述
classかどうかを指定するのは、最後(一番右)に記述したもののみであるため、
それ以外はclassやmoduleの判断を柔軟に行ってくれます。

module TopKlass
end

class TopKlass::InnerKlass
end

# エラーにならない

ネスト元のオブジェクトがなかった時に例外を出すかどうか

・中に記述
以下の例の場合、TopKlassを別で定義していなかった場合、
新たにTopKlassを定義してくれるため例外は発生しません。

class TopKlass
  class InnerKlass
  end
end

・ネームスペースを用いて記述

以下の場合は、別でTopKlassを定義していなかった場合例外を出します。
新たにTopKlassを定義はしてくれません。

class TopKlass::InnerKlass
end

# => uninitialized constant TopKlass (NameError)

おわり

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

nginx+rbenv+Redmine+unicornをサブディレクトリ付きで動かそうとした際に対応しておきたいこと

はじめに

もともとは、Redmine(今回は4.1.1を採用)を当方のVPSサーバーにインストールするために、このサイトを参考にして構築していました。当方はWebサーバーにnginxを使用しているため、有効活用することにしました。

Webアプリのファイルはすべて /usr/share/nginx/html に収めています。

また、当方のサイトはメインサイトが有るため、サブディレクトリ(例:/hoge)でアクセスするようにしました。

そのときに発生した色々な問題と解決方法をここにメモすることにしました。

1.redmine-unicorn.serviceで起動するRubyのパスを指定

当方がメインで使用しているRubyは2.7.2。しかし、Redmine(4.1.1)は2.7に非対応…そのため、すでにrbenvを使用してインストールしている2.6.4を直接使用するために、redmine-unicorn.serviceのExecStartを修正する必要があります。

Ruby2.6.4をインストールしているディレクトリを/usr/local/rbenv/versions/2.6.4とすると、設定は以下のようになります。

[編集前]
ExecStart= bundle exec "unicorn_rails -c config/unicorn.rb -E production"
[編集後]
ExecStart= /usr/local/rbenv/versions/2.6.4/bin/bundle exec "PATH=$PATH:/usr/local/rbenv/versions/2.6.4/bin /usr/local/rbenv/versions/2.6.4/bin/unicorn_rails -c /usr/share/nginx/html/redmine/config/unicorn.rb -E production"

2.最新のRedminを起動する際に必要な設定

unicornを使って最新のRedmineを起動する際、ExecStartに -Dオプションを付けないとエラーになります。

[変更前]
ExecStart=/usr/local/rbenv/versions/2.6.4/bin/bundle exec "PATH=$PATH:/usr/local/rbenv/versions/2.6.4/bin /usr/local/rbenv/versions/2.6.4/bin/unicorn_rails -c /usr/share/nginx/html/redmine/config/unicorn.rb -E production"

[変更後]
ExecStart=/usr/local/rbenv/versions/2.6.4/bin/bundle exec "(略) -E production -D"

参考: https://teratail.com/questions/186552

3.ソケットは使わずhttpポートを使用

unicorn_redmine.sockでconnection refusedが起きるときは、unixソケットを使わず、httpポートを使うのも手です

  • config/unicorn.rb
[変更前]
listen  File.expand_path('tmp/unicorn_redmine.sock', app_path)

[変更後]
listen 3000
  • nginx/conf.d/(redmine用コンフィグファイル名)
[変更前]
upstream unicorn-redmine {
  server unix:/usr/share/nginx/html/redmine/tmp/unicorn_redmine.sock;
}

[変更後]
upstream unicorn-redmine {
  server 127.0.0.1:3000;
}

一旦サービスを落とした後、tmp/unicorn.pidが残っていればさっさと削除しちゃいましょう。

参考: https://teratail.com/questions/87083

4.Redmine起動の際、オプションにサブディレクトリを指定

redmine-unicorn.serviceのExecStartに --pathオプションでサブディレクトリを指定します。

[変更前]
ExecStart=/usr/local/rbenv/versions/2.6.4/bin/bundle exec "PATH=$PATH:/usr/local/rbenv/versions/2.6.4/bin /usr/local/rbenv/versions/2.6.4/bin/unicorn_rails -c /usr/share/nginx/html/redmine/config/unicorn.rb -E production -D"

[変更後]
ExecStart=/usr/local/rbenv/versions/2.6.4/bin/bundle exec "(略) -D --path /hoge"

参考: https://qiita.com/61503891/items/732d9c123c39e35e97eb

5.config.ruをリネーム

ちゃんとここまで設定しているのにエラーが発生してまうので調べてみると、なんとconfig.ruが悪さしているという記事を見つけました。
config.ruが無くてもunicornがなんとかしてくれるそうなので、削除するかリネームしちゃったほうがいいでしょう。

mv config.ru config.ru.org

6.静的ファイルにアクセスさせるための設定

サブディレクトリ /redmine が付いているため、そのまま静的ファイルにアクセスしようとすると404エラーが返ってきます。
そのため、nginxのルーティング設定を使って、サーバー側のディレクトリに正しく誘導する必要があります。

        location ~ ^/redmine/.*/.*.(css|js|jpe?g|png|gif|ico|swf|woff2|ttf)$ {
                root    /usr/share/nginx/html/redmine/public;
                try_files $uri @app;
        }

さいごに

これらの設定を経て、無事にRedmineがきれいに起動いたしました。めっちゃ感動…
気持ちえー!

redmine_succeed.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rbenvを使ってunicornをデーモンとして起動する際に忘れがちなこと

些細なメモ程度の内容ですが、すごく忘れがちなもので…。

もともとは、Redmineを当方のVPSサーバーにインストールするために、このサイトを参考にしてUnicornをデーモン化しようとしてserviceコマンドを使って立ち上げてみると…。

10月 11 20:36:46 (サーバーのアドレス) redmine-unicorn[25435]: /usr/bin/env: ruby: そのようなファイルやディレクトリはありません

どうやら、unicorn_rails内でrubyのパスが通っていないのでエラーが出た模様です。
当方がメインで使用しているRubyは2.7.2。しかし、Redmine(4.1.1)は2.7に非対応…そのため、すでにrbenvを使用してインストールしている2.6.4を直接使用することにしたのですが、それが裏目に出た模様です。
悩みながらトイレに行っている間に解決方法を思いつきました。
単純に、unicorn_railsを起動しているコマンドでパスを通してやるとエラー無くUnicornが起動しました。

[編集前]
ExecStart= /usr/local/rbenv/versions/2.6.4/bin/bundle exec "/usr/local/rbenv/versions/2.6.4/bin/unicorn_rails -c /home/cyross/redmine/config/unicorn.rb -E production"
[編集後]
ExecStart= /usr/local/rbenv/versions/2.6.4/bin/bundle exec "PATH=$PATH:/usr/local/rbenv/versions/2.6.4/bin /usr/local/rbenv/versions/2.6.4/bin/unicorn_rails -c /home/cyross/redmine/config/unicorn.rb -E production"

というわけで、ちょっとしたメモでした。

おまけ1

unicornを使ってRailsを起動する際、-Dオプションを付けないとエラーになります。

参考: https://teratail.com/questions/186552

おまけ2

unicorn_redmine.sockでconnection refusedが起きるときは、unixソケットを使わず、httpポートを使うのも手です

参考: https://teratail.com/questions/87083

おまけ3

当方はredmineのURLをサブディレクトリで指定するようにしていますが、その際、redmine-unicorn.serviceを修正する必要があります。

参考: https://qiita.com/61503891/items/732d9c123c39e35e97eb

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

redirect_toとrenderの違い

はじめに

処理を書くたびにまだよく混同してしまうので、
パッとすぐ思い出せるようにメモしておきます。

違い

redirect_to

user_controller.rb
def ~
 # 処理

 redirect_to("/app/posts/new")
end

指定先:
URL(/URL/〜/〜/)

ルート:
controller → URL → route → controller → view

主な用途:
データの更新や削除が必要な場合など → 「適切なcontrollerでの処理が必要」なとき

render

user_controller.rb
def ~
 # 処理

 render("user/edit")
end

指定先:
ディレクトリ/ビュー

ルート:
controller → view

主な用途:
ログインや入力形式に失敗した場合など → 「ただエラーを表示させたい」とき

参考

【Rails】renderとredirect_toの違いと使い分け
【Rails】flashメッセージを使用して簡易メッセージを表示させる詳しい方法と解説

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

nested_formでf.link_to_add以外をクリックしprefillした要素を追加する

通常の使い方では、 link_to_addというformメソッドで表示されるaタグで要素を追加しますが、
今回私が実装したパターンは、canvasをクリックした座標をnested_formの要素を追加し、その要素に座標をprefillする、というものです。

調べた感じだと、link_to_addメソッドはblueprintなどをふくむDOM構造に依存したイベントで動いているため、link_to_addが内部で使っているjavascriptのメソッドを使ってきれいに実装することはできませんでした。

従って、基本的な実装方針は、canvasのクリックイベントハンドラーで、グローバルなストアに座標を書き込み、 nested:fieldAdded イベントで、グローバルなストアから座標を読み取る、という外部を中継する実装にしました。

function handleClick(e) {
[...]
  var linkToAdd = $('[data-blueprint-id="connectors_fields_blueprint"]')
  linkToAdd.data('tmp-x', Math.floor(mouseX));
  linkToAdd.data('tmp-y', Math.floor(mouseY));
  linkToAdd.click();
}     
  $(document).on('nested:fieldAdded:connectors', function(event){
    var linkToAdd = $('[data-blueprint-id="connectors_fields_blueprint"]')
    event.field.find('input[data-x]').val(linkToAdd.data('tmp-x')) && linkToAdd.data('tmp-x', null);
    event.field.find('input[data-y]').val(linkToAdd.data('tmp-y')) && linkToAdd.data('tmp-y', null);
[...]

もっとよい方法を知っていればおしえてください。

おわり

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[rails]herokuのデプロイエラーActionView::Template::Error (Mysql2::Error: Table --- doesn't exist):

herokuにデプロイした際にエラーが出てしまいました。We are sorry...というやつです...

エラー内容

heroku logs --tail --app [app名] でログを確認したところ以下mのようなエラーが出ました
これはあるテーブルでエラーが出ているみたいですね

ActionView::Template::Error (Mysql2::Error: Table 'heroku----' doesn't exist):

考えられる原因

調べましたところ、このエラー文で考えられる原因は以下の3点でした(他にもある可能性はあります )

1railsのバージョンの問題

rails5.0と5.2の場合はこのようなエラーが出ることがあるみたいです
migrationファイルの書き方,型に問題があるといった点で問題があるみたいです
私は6.0であまり詳しくしらべてませんので もし当てはまるかたは調べてみてください

2 調べたときにupになっていない or NO FILEがある。

ターミナルでrails db:migrate:statusをうって確認してみてください
no fileがあった場合は削除しなければなりません(別の記事に方法載せてます。)

3 heroku上ののSQLでちゃんとmigrateされていない

heroku run rails db:migrate

これで直りました。

というかしっかりエラー文を読むと明らかにこれでが原因でしかないのかもしれません。...

以上でした

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby on Rails]色の割合を明示する円グラフを実装する

自身が欲しいのと、作ってみたら面白そうという思いの元、現在、自身の服を管理できる「クローゼットアプリ」のようなものを、個人で作成しています。
そこで自身の服の色の割合を、円グラフでわかりやすく表示できれば、いいなと思い今回実装いたしました。

開発環境

Ruby 2.5.1p57
Rails 5.2.4.4
使用gem
  ・active_hash
  ・chartkick
  ・chartable

実際に作っていく

今回実際の色のデータをどこに持たせるか非常に悩みましたが、active_hashを使用し、モデルにハッシュ形式で、データを持たせ、そのIDを「colors」というデータベースに保存することにしました。

まずGemfileに下記を記述します。

Gemfile
#~省略~
gem 'active_hash'
gem "chartkick"
gem 'chartable'
#~省略~

application.jsに下記を記述します。

application.js
//= require Chart.bundle
//= require chartkick

そしてActive_hashを用いて、実際の色データを持たせたモデルがこちらです。

color_data.rb
class ColorData < ActiveHash::Base
  self.data = [
    { id: 1, name: 'ホワイト', backcolor: "#fff" },
    { id: 2, name: 'ブラック', backcolor: "#000" },
    { id: 3, name: 'グレー', backcolor: "#808080" },
    { id: 4, name: 'ブラウン', backcolor: "#660000" },
    { id: 5, name: 'ベージュ', backcolor: "#FFE4C4" },
    { id: 6, name: 'グリーン', backcolor: "#006400" },
    { id: 7, name: 'ブルー', backcolor: "#0000CD" },
    { id: 8, name: 'パープル', backcolor: "#8B008B" },
    { id: 9, name: 'イエロー', backcolor: "#FFFF00" },
    { id: 10, name: 'ピンク', backcolor: "#FF82B2" },
    { id: 11, name: 'レッド', backcolor: "#FF0000" },
    { id: 12, name: 'シルバー', backcolor: "#C0C0C0" },
    { id: 13, name: 'ゴールド', backcolor: "#DAA520" }
  ]
end

こんな感じで書きました。「backcolor」というkeyは円グラフのそれぞれの項目に指定した色を渡すためのデータです。

そしてmodel。
コントローラーに、グラフのデータは、ハッシュ形式で渡し、背景色のデータは、配列として渡したかったので、かなり助長で、同じことを繰り返している冗長なコードになっています、、、。ここはもっといいやり方を模索します。

color.rb
class Color < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :color_data
  class << self
    #グラフに渡すハッシュデータを形成するメソッド
    def color_data_acquisition_for_graphs
      colors = all
      color_graph_data = {}
      colors.each_with_index do |color, index|
        color_graph_data = { color.color_data.name => 1 } if index.zero?
        #eachでDBから取得したデータを回し、既に、keyとして存在しているかをチェックする
        #もう既に存在していれば割合の基準となるvalueに1を足していく
        if color_graph_data.key?(color.color_data.name)
          color_graph_data[color.color_data.name] += 1
        else
          color_graph_data[color.color_data.name] = 1
        end
      end
      color_graph_data
    end

    def background_color_data_acquisition_for_graphs
      colors = all
      color_graph_data = {}
      background_colors = []
      colors.each_with_index do |color, index|
        if index.zero?
          color_graph_data = { color.color_data.name => 1 }
          #背景色のデータ(backcolorのデータ)を追加していく
          background_colors << color.color_data.backcolor
        end
        if color_graph_data.key?(color.color_data.name)
          color_graph_data[color.color_data.name] += 1
        else
          color_graph_data[color.color_data.name] = 1
          #まだ取り込んでいないkeyが来た時にbackcolorを追加していくために順番が守られる
          background_colors << color.color_data.backcolor
        end
      end
      background_colors
    end
  end
end

ここは参考にしないでください笑(いい書き方があればどなたか、、、)

そしてここで作成したデータをコントローラに渡します。

closet_controller.rb
class ClosetController < ApplicationController
  def index
    @color_graph_data = Color.color_data_acquisition_for_graphs
    @background_colors = Color.background_color_data_acquisition_for_graphs
  end
end

そしてビューにグラフ用の集計データと、グラフに色をつける用のデータを渡します。

あとは表示するだけです。

index.html.slim
= pie_chart @color_graph_data, colors: @background_colors

これだけで、、、

スクリーンショット 2020-10-11 14.34.47.png

このように表示する事ができます。

ちなみにメニューの項目が要らなければ、config/initializers/以下に「chartkick.rb」というファイルを作成し、オプションを書く事で非表示にすることもできます。

chartkick.rb
Chartkick.options = {
  legend: false
}

こうすることで、、、

スクリーンショット 2020-10-11 14.39.00.png

初めは、色によってバックグラウンドに指定する色を条件分岐したりしないといけないのかなと思ったりもしましたが、そもそものActive_hashの時点でそれぞれの背景色の値を持たせることを思いつけたので良かったです。

個人アプリでは史上最多の28個ものテーブルを持つ開発になるので楽しみながら頑張っていきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails 6.0 の環境構築メモ

はじめに

個人のWindows10のPCに初めてRuby on Railsの環境構築するまでの備忘録。
ちなみに筆者は、Web系はLinux(CentOS)とWindows10のCakaPHPをおさわりしたことしかない。

Ruby 2.6.6 のインストール

Ruby2.7とRails6.0(あるいは周辺gem)の組み合わせによっては警告が発生する場合があるとのことなので、Ruby2.6.6を選択。

  • 下記リンクにて「rubyinstaller-devkit-2.6.6-1-x64.exe」をダウンロード。
    https://rubyinstaller.org/downloads/

  • ここで後のコマンドラインによるインストール処理にてエラーが発生するため、事前にWindowsFWとセキュリティソフトを停止しておく。

  • ダウンロードしたインストーラーを実行。
    「Use UTF-8 as default external encoding.」にチェック
    「MSYS2 development toolchain 2019-10-01」にチェック
    エディタ「VisualStudioCode」を選択

  • 表示されたコマンドラインのRubyInstallerにて、Enterして実行。

以上でRubyのインストールが完了したので、コマンドラインでバージョンを確認。

> ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]

ついでにgemもバージョン確認。

gem -v
3.0.3

Gitインストール

  • 下記サイトよりインストーラーをダウンロード。

    https://gitforwindows.org/

  • ダウンロードしたインストーラーを実行。
    「Use Visual Stadio Code as Git's default editor」を選択
    「Use the OpenSSL library」を選択
    extra options はよしなに

以上で、Windowsスタートメニューに「Git Bush」などのアイコンが追加されていることを確認して終了。

Node.jsのインストール

Node.jsをバージョン管理するためにnodistを使用。

  • 下記サイトよりnodistインストーラーをダウンロード。「NodistSetup-v0.9.1.exe」

    https://qiita.com/satoyan419/items/56e0b5f35912b9374305

  • nodistをインストール。
    ※「PATH not update,~」のエラーが出たので以下をシステムの環境変数に追加。
    【Path】C:\Program Files (x86)\Nodist\bin
    【NODIST_PREFIX(新規)】C:\Program Files (x86)\Nodist
    【PATH(新規)】%NODIST_PREFIX%\bin
    【NODE_PATH(新規)】%PATH%\node_modules

  • nodistバージョン確認。

>nodist -v
0.9.1
  • Node.jsのインストール。 12系の最新を選択(End-of-life:2022-04-30)
>nodist + 12.19.0
>nodist 12.19.0
>node -v
v12.19.0
>nodist npm 6.14.8
>npm -v
6.14.8

※npxのインストールはしていない。

yarnのインストール

>npm install -g yarn
>yarn -v
1.22.10

bndlerのアップデート

バージョンが古かったため、最新に更新。

>gem install bundler
>bundler -v
Bundler version 2.1.4

SQLite3のインストール

テンポラリーファイルのパスのユーザー名が全角の場合、一時ファイルの作成に失敗するので、先にテンポラリーファイルを変更してからインストール。

>set TEMP=C:\Temp
>set TMP=C:\Temp
>gem install sqlite3

Rails6.0.3のインストール

>gem install rails -v 6.0.3
>rails -v 
Rails 6.0.3

以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails] deviseを使って現在ログインしているユーザーの情報を取得する

回答

@user = current_userでOK

  def index
    @user = current_user
    @gears = Gear.where(user_id: @user.id)
  end

総括

deviseを使うとログイン周りが楽すぎる:metal:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails新規開発時のスピードを極限まで高めるテンプレートを公開してみた

これはなに?

Rails の初期設定ってめんどくさくないですか?
rails new してからの単純作業。

せっかくスピード感があるフレームワークなのに最初の単純作業はほぼ同じことを毎回していますし、地味に時間もかかるので嫌でした。
今や Docker を使ってサクッと環境を構築するのは当然ですが、それでもやっぱり面倒。

特に、

  • RSpecのセットアップ
  • devise の設定
  • お決まりの Gem を入れる手間

この辺が嫌いでしたし、皆さんにもやって欲しくない!!

そうだ、テンプレートを作ろう

んで、どうせなら皆さんにも公開して是非使って頂こう、あわよくば改善案も貰ってしまおうという非常に厚かましい企画となっております。
ちなみに他にもテンプレートを公開されている方はいらっしゃいましたが少し古くなっていますし、Docker を使っていないことも多かったです。

今回は Docker を使って爆速で Rails 開発を始められるテンプレートを丸ごと公開します!!

バージョンなど

  • ruby:2.6.6
  • rails 6.0.3
  • postgresql:12.3

こららのモダンな環境をサクッと構築してすぐに開発に取り掛かれます!!

どんな人におすすめか

主に個人開発や簡単なRailsアプリをサクッと作りたい場面で有用だと思います。
逆にメジャーとは言え、使わない Gem も入ることになると思うので(最初に取り除けば全く問題ありませんが)、スピード重視じゃない場合には合わないかもしれません。

行った設定等の解説

リポジトリはこちらです ?
https://github.com/tatsuro-m/rails_base_app

基本的には README に手順が書いてあるので問題なく使えると思います。
手順が多いようにも見えますが、本当にすぐに終わります。

  • devise の初期設定(rails generate devise:install を実行。viewの生成はしていない。)
  • rspec のセットアップ(システムスペックを含む)
  • test ディレクトリの削除(使わないので)
  • database.yml の編集(postgresコンテナに設定した環境変数と合わせてあります)
  • .env.gitignore への追加
  • webpack-dev-server の設定

こんな感じで Docker イメージをビルドして起動 + 最低限必要なコマンドを何個か打つ
ぐらいでサクッと Web アプリケーションの開発が始められると思います。

んで、 Gem 何入れたの?

Gemfiile
gem 'devise'
gem 'devise-i18n'
gem 'dotenv-rails'
gem 'ransack'
gem 'kaminari'
gem 'carrierwave'
gem 'mini_magick'
gem 'fog-aws'
gem 'rails-i18n'
gem 'draper'
gem 'pundit'

デフォルトのものに加えて、こちら入れました。どれも定番ですね。必要な Gem があれば Gemfile に書き込んでから docker-compose build でももちろん大丈夫です。

今後の改善案など

  • CircleCI で rubocop と RSpec を走らせる設定ファイルはもう定番だし入れても良いかもしれない(不要なら消せば良いだけですし) 。。。
  • rails が動いているコンテナの中に SystemSpec 起動用の chrome を入れているけど、コンテナを分けるべきかもしれない

他にも何かあればコメントください。PR もお待ちしてます!!


どなたかのお役に立てたら幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【RubyonRails】地域猫を幸せにするサービスを作ってみる

 はじめに

猫が好きです。
通勤で見かける猫、人の家の猫、癒しです。
幸せな猫が増えて欲しいと切に願っています。
昨年から、近所の駅に黒猫が住み着き、以降その子をダイコクちゃんと勝手に命名し、可愛がっています。

一方、野良猫には手放しに可愛いだけで済まない問題も含まれています。
虐待や無責任な餌やりなど。
地域猫に対する様々な活動がありました。

その中で、TNR活動なるものがあることを知りました。
さくらねこ♥TNRとは (TNR先行型地域猫) – どうぶつ基金

このような活動が広まったり、無責任な餌やりによって不幸になる猫が減ることを願い、今回のサービスを考えました。

地域猫を住民でしっかり管理できるようなサービスとなれば幸いです。

環境

MacBook Air2020
Ruby2.7.1
Rails6.0.3.4
MySQL

構想

ユーザー(住民)は以下のことが可能です

  • 健康状態や食事、去勢手術の状況の情報確認
  • 地域猫の餌やりや去勢手術の状況を確認できる
  • 地域猫の画像閲覧
  • 地域猫の登録
  • 地域猫の餌やり情報の登録、画像投稿

設計(ER図)

スクリーンショット 2020-10-11 17.41.49.png

最後に

今後、地道に作成していきます。
進捗をお伝えしていくつもりですのでよろしくお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsのテストコード時にBasic認証でエラーが出た時の対処法

はじめに

今回はコントローラーの単体テストコード実装時に出た表題のエラーの件について記述したいと思います。ですがその前にまずはBasic認証について軽く説明したいと思います。

Basic認証とは

Webサイトにアクセス制限をかける方法の一つ。その中でも最も簡易的に制限をかけることができる方法がベーシック認証(Basic認証)です。ベーシック認証(Basic認証)はWebサーバーに付随している機能の1つでファイルに数行の記述をするだけで簡単にアクセス制限をかけることが可能です。

「Basic認証の参考画像」
Image from Gyazo

「引用させて頂いたサイト」
ベーシック認証(Basic認証)とは?設定方法と注意点・エラーになる原因を解説

エラー内容

それでは改めまして今回の本題について説明させて頂きます。
まず初めにコントローラーの単体テストコード実行時に下記のエラーが出ました。

ターミナル
bundle exec rspec spec/requests/items_spec.rb

~中略~

Failures:

  1) ItemsController GET /index indexアクションにリクエストすると正常にレスポンスが返ってくる
     Failure/Error: expect(response.status).to eq 200

       expected: 200
            got: 401

       (compared using ==)
     # ./spec/requests/items_spec.rb:28:in `block (3 levels) in <top (required)>'

  2) ItemsController GET /index indexアクションにリクエストするとレスポンスに出品済みの商品名が存在する
     Failure/Error: expect(response.body).to include @item.goods

       expected "HTTP Basic: Access denied.\n" to include "Custard Apples Daikon"
       Diff:
       @@ -1 +1 @@
       -Custard Apples Daikon
       +HTTP Basic: Access denied.

~中略~

そしてエラーの内容を検証したところ原因と思われる部分は下記の2点です。

ターミナル
1)
       expected: 200
            got: 401

2)
expected "HTTP Basic: Access denied.\n" to include 

まず1つ目はexpectedで「200」(成功)を期待していますが実際のレスポンスは「401」(未認証)でしたという内容です。

そして2つ目の方でBasicという単語が出てるので設定していたBasic認証ではじかれているのだろうと仮定しました。
(まあ英語の内容(HTTP Basic: Access denied)もシンプルにHTTPのBasicでアクセスが拒絶されました。みたいな意味合いなので)

上記の2つのエラー内容から「application_controller.rb」内に設定していたBasic認証の部分を通れていないせいでテストコードが失敗したと判断しました。

そこで自分はテストコードの実行時だけは該当のBasic認証の部分をコメントアウトすることにしました。

application_controller.rb
class ApplicationController < ActionController::Base
  before_action :basic_auth (この行をコメントアウトする)

そして再度単体テストコードを実行

ターミナル
 bundle exec rspec spec/requests/items_spec.rb

ItemsController
  GET /index
    indexアクションにリクエストすると正常にレスポンスが返ってくる
    indexアクションにリクエストするとレスポンスに出品済みの商品名が存在する
    indexアクションにリクエストするとレスポンスに出品済みの商品の画像が存在する
    indexアクションにリクエストするとレスポンスに出品済みの商品の販売価格が存在する
    indexアクションにリクエストするとレスポンスに新規投稿商品一覧が存在する

Finished in 3.21 seconds (files took 4.76 seconds to load)
5 examples, 0 failures

上記の通り無事にテストコードを実行することが出来ました。

おわりに

調べているとBasic認証の部分を残したままでもテストコードを行う方法があるみたいだったのですが少し複雑そうだったため今回は簡単なこちらの方法にしてみました。

当記事で参考にさせて頂いたサイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RedmineではProject.find(identifier)でプロジェクトを取得できる

redmineのプラグインチュートリアル でも多様されている表現ですが、個人的にはfind()はidのみに使った方が良いと思います。

なぜできるか?

Redmineのコードで以下のようにオーバーライドしているから。

app/models/project.rb

  def self.find(*args)
    if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
      project = find_by_identifier(*args)
      raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil?
      project
    else
      super
    end
  end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RedmineではProject.find(<identifier>)でプロジェクトを取得できる

redmineのプラグインチュートリアル でも多様されている表現ですが、個人的にはfind()はidのみに使った方が良いと思います。

なぜできるか?

Redmineのコードで以下のようにオーバーライドしているから。

app/models/project.rb

  def self.find(*args)
    if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
      project = find_by_identifier(*args)
      raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil?
      project
    else
      super
    end
  end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby クラスとインスタンス

はじめに

これは学習用のメモになります。

Rubyでは、「オブジェクト」や「変数」などたくさん用語が出てきて大変なので、少しずつでも理解を早めるために自分なりにアウトプットしていきたいと思います。
もし、違うところがあればコメントしていただけると幸いです。

クラスとインスタンスとは?

クラスとインスタンスを理解するためには「オブジェクト」と「メソッド」という言葉を理解する必要があります。

説明は以下...

オブジェクト

オブジェクトとは「Rubyにおける全てのデータ」のことです。

例えば「おはよう」といったような文字は「文字列オブジェクト」、「123」といった数字は「数値オブジェクト」と呼ばれています。

メソッド

オブジェクトが持つ「処理」のことをメソッドと言います。
Rubyのオブジェクトは全て「メソッド」を持っています。
例えばこんな感じで、

・文字列オブジェクト → lengthメソッド → 文字数を数える
・数値オブジェクト → to_sメソッド → 整数に変換する

といったようにオブジェクトの種類ごとに持っているメソッドが違います。
例えると、人はそれぞれ性格が違うよねってことです。

クラス

クラスとは「共通のプロパティとメソッドをまとめたもの」のことで、今回は、「クルマの設計図」を例として考えます。
クルマを作る時には設計図が必要ですが、どのクルマにも共通する部分があるわけです(ハンドル・ブレーキで「加速する」など)。その「共通した部分を設計図にしてまとめよう」ってことです。

つまり、クラス(設計図)を作って、他のクルマを作る時でも使えるようにできる仕組みです。

インスタンス

インスタンスは「クラスから属性や処理を受け継いでできたオブジェクト」のことです。

クラス(設計図)をベースに作られたオブジェクト(クルマ)といえばわかりやすいでしょうか。必要最低限の部分を引き継いでいるので、「ハンドルがあって〜」一からなどど設計図を作らなくて済むのがメリットになります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

失敗したrspecのテストをgithubのcheck annotationsでみられるようにする

GithubActionsでCICDフローを回せて便利!
でもrspecがこけたときに、エラー箇所をしらべるのに難儀する。
Github Checksでみられたらよさそう。

reviewdogでアップロードしようと思ったけれど、サポートされているエラーフォーマットはなかった。
https://github.com/reviewdog/reviewdog#available-pre-defined-errorformat

サポートするためのPRつくれるかなとおもってソースをみていたら、 Reviewdog Diagnostic Format というものが提案されている。
https://github.com/reviewdog/reviewdog/tree/master/proto/rdf

パーサーを書くより、こっちのフォーマットに合わせて、rspecの出力を加工するほうが良さそう。
でもまだ正式版じゃないみたい。SARIF良さそう。
なのでRDFormatではなく、既存の入力フォーマットに合わせてrspecのフォーマッタを作ることにする。
https://github.com/reviewdog/reviewdog#input-format

  • errorformat
  • checkstyle XML format

を試作してみて、動作確認がしやすかった checkstyle にする。

XMLがなつかしい。

https://github.com/astronoka/rspec-checkstyle_formatter
フォーマッタをつくってgemにしました。

実装中、mysqlかなにかのエラーで出力される asciiのカラーコード \e[0;34m 的なやつでXMLのビルダー/パーサーがエラーになったりして
そういえばこういうことでエラーになったことあったなと、ますます懐かしい気持ちになる。

GithubActionsでの記述例

name: CI

on: push

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 2.7.1

    - name: Restore gems
      uses: actions/cache@v2
      with:
        path: vendor/bundle
        key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
        restore-keys: |
          ${{ runner.os }}-gems-

    - name: Run rspec
      run: |
        bundle config path vendor/bundle
        bundle install --jobs 4 --retry 3
        bundle exec rspec \
          --no-fail-fast \
          --format RSpec::CheckstyleFormatter \
          --out /tmp/rspec_result.xml

    - name: Upload rspec result
      if: always()
      uses: actions/upload-artifact@v2
      with:
        name: rspec_result.xml
        path: /tmp/rspec_result.xml

    - name: Install reviewdog
      if: always()
      uses: reviewdog/action-setup@v1
      with:
        reviewdog_version: latest

    - name: Report rspec error
      if: always()
      env:
        REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        cat /tmp/rspec_result.xml | reviewdog -name=rspec -f=checkstyle -reporter=github-check -filter-mode=nofilter

こんなかんじ。

image.png

reviewdog素晴らしい :sparkles:

linter向けのフォーマットで渡すのはどうなのだろうと思いつつ
了。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rspecの失敗したテストをgithubのcheck annotationsでみられるようにする

GithubActionsでCICDフローを回せて便利!
でもrspecがこけたときに、エラー箇所をしらべるのに難儀する。
Github Checksでみられたらよさそう。

reviewdogでアップロードしようと思ったけれど、サポートされているエラーフォーマットはなかった。
https://github.com/reviewdog/reviewdog#available-pre-defined-errorformat

サポートするためのPRつくれるかなとおもってソースをみていたら、 Reviewdog Diagnostic Format というものが提案されている。
https://github.com/reviewdog/reviewdog/tree/master/proto/rdf

パーサーを書くより、こっちのフォーマットに合わせて、rspecの出力を加工するほうが良さそう。
でもまだ検討中。SARIF良さそう。
なのでRDFormatではなく、既存の入力フォーマットに合わせてrspecのフォーマッタを作ることにする。
https://github.com/reviewdog/reviewdog#input-format

  • errorformat
  • checkstyle XML format

を試作してみて、動作確認がしやすかった checkstyle でいくことにする。

XML自体がなつかしい。

実装中、mysqlかなにかのエラーで出力される asciiのカラーコード \e[0;34m 的なやつでXMLのビルダー/パーサーがエラーになったりして
そういえばこういうことでエラーになったことあったなと、ますます懐かしい気持ちになる。

https://github.com/astronoka/rspec-checkstyle_formatter
フォーマッタをつくってgemにしました。

GithubActionsでの記述例

name: CI

on: push

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 2.7.1

    - name: Restore gems
      uses: actions/cache@v2
      with:
        path: vendor/bundle
        key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
        restore-keys: |
          ${{ runner.os }}-gems-

    - name: Run rspec
      run: |
        bundle config path vendor/bundle
        bundle install --jobs 4 --retry 3
        bundle exec rspec \
          --no-fail-fast \
          --format RSpec::CheckstyleFormatter \
          --out /tmp/rspec_result.xml

    - name: Upload rspec result
      if: always()
      uses: actions/upload-artifact@v2
      with:
        name: rspec_result.xml
        path: /tmp/rspec_result.xml

    - name: Install reviewdog
      if: always()
      uses: reviewdog/action-setup@v1
      with:
        reviewdog_version: latest

    - name: Report rspec error
      if: always()
      env:
        REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        cat /tmp/rspec_result.xml | reviewdog -name=rspec -f=checkstyle -reporter=github-check -filter-mode=nofilter

こんなかんじ。

image.png

reviewdog素晴らしい :sparkles:

了。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

28歳地方公務員がプログラミングを始めて8.5ヶ月でweb系自社開発企業に転職成功した話

私について

1992年生まれ28歳
地方公務員5年目
早大卒のド文系
プログラミング経験は特にありませんでした
数学はじめ理数系も全くの未経験

誰に向けて書いた?

未経験からweb系エンジニアにジョブチェンジされようとしている方

学習内容

おおよそのタイムライン

2019年12月 Progate
2020年1月 Railsチュートリアル・インスタクローン作成
2020年2月 現場で使えるRuby on Rails5速習実践ガイド
2020年3月 ポートフォリオ作成
2020年4月 ポートフォリオ作成
2020年5月 ポートフォリオ作成
2020年6月 面接
2020年7月 内定

勉強しているときの生活リズム

平日:出勤前後に各1時間
休日:8時間

実際にやったこととかけた時間

Progate Ruby on Rails  3周  40時間

〜環境構築〜 3時間

小学生でも分かるRuby on Rails入門 5時間

Railsチュートリアル

一周目:ざっと流し読み 10時間
二周目:テスト、デプロイ、演習除く 20.5時間
三周目:省略なし(11章の途中でエラーが発生し、直せなかった・・・ので、そこからはコーディング及びデプロイはしていません) 25時間

インスタクローン作成 52.5時間

現場で使えるRuby on Rails5速習実践ガイド 一周 17時間

ポートフォリオ作成 185.5時間

プログラミングスクールについて

某キャンプさんにお世話になりました。
スクールについては自走できる人については必要ないと考えています。
自分の勉強スタイルや、スクールで何を得たいか、外からの強制力が必要かどうかを考えて使うかを決めていきましょう。

いざ、転職活動

100数十社にエントリー、しかし・・・度重なるお祈り、そして内定

転職活動は6月〜7月でした。
ちょうどコロナで各企業が採用を絞っている時期でした。

今は求人プラットフォームが様々ありますが、私はwantedly一択でした。
GREENやエージェントも使いましたが、ピンと来る企業がなかったため途中からは使っていません。
エージェントは、未経験だとSIerやSESの企業ばかり勧めてきます。

上記にもあるように100数十社にエントリーした私ですが、書類を通過したのはわずか10社程度でした。
未経験からの転職は厳しいと聞いていましたが、まさかこれほどまでとは・・・。

最終的には、トントン拍子に選考が進んだ企業様から内定をいただくことになりました。
自社開発を行っているベンチャー企業でした。

勉強開始からこれまでを振り返って

僭越ながら二点ほど。

・勉強は短期集中
長くなってしまうとどうしてもモチベーションが下がってしまいますし、知識の定着も悪くなります。
「◯月○日までにこれをやる!」といったように目標期日を(厳しめに)設けて進めていきましょう。

・未経験からのエントリーはとにかく量
未経験からの転職は想像を超える大変さでした。
質の高いポートフォリオを作りきり、面接準備も整ったらどんどんエントリーしていきましょう。
どうしても入りたい企業があれば話は別ですが、基本的に企業は選ばずにエントリーしていきます(そのうち選んでいられなくなるかと思います・・・)。
「実務未経験!」と書いてあった求人はもちろん、大々的に謳っていない企業にもガンガンエントリーしました。
お祈りが大量に来ると思いますが、めげずにエントリーしてください!

最後までお読みいただきありがとうございます。
皆さんにもいいご縁がありますように!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails db:migrateでエラーが出た((StandardError: An error has occurred, this and all later migrations canceled:)時の対処法

rails db:migrate でエラーが出ることがあります。私の場合は何故かちょいちょい何かしらのエラーが出るので対処法を調べてみました。(私自身ruby,rails共に初学者です。この記事は初学者の方の参考になればという思いと、私の学習のために執筆しています。)

== 20201011010946 CreatePosts: migrating ======================================
-- create_table(:posts)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DuplicateTable: ERROR:  relation "posts" already exists

(つづく)

rails db:migrateでエラーが出る原因は?

今回のStandardErrorに関しては、migrateを実行したが実行中に何らかの原因でエラーが起きてしまい、テーブルは作成されているけどmigtate事態は未実行扱いとなっている状態。

つまり、システム側のちょっとしたエラーで中断された状態って感じだと思います。

しかし、エラー文には/post_bootstrap_app/db/migrate/20201011010946_create_posts.rb:3:in `change'などと、あたかもそこにミスがあるかのように書かれていて「俺、そんなとこいじってへんのやけど?」状態となり、一瞬混乱します。

rails db:migrateでエラー(StandardError)が出た時の対処方法

rails db:migrate:reset
※migrateの実行を一旦リセット

rails db:migrate
※改めてrails db:migrateを実行

対処方法を私なりに少し調べてみたのですが、中断されたmigrateを一旦リセットでなかったことにして、再度migrateでやり直せば上手くいくとのことで、この方法を実際に実行してみました。

その結果、、、何事もなかったかのようにdb:migrateに成功しました!

今回のまとめ

しょっぱなのデータベース作成時にエラーが出たら「まだ大して何も記述していないのに何故にエラー!?」と混乱するのは初学者あるあるだと思います。

しかし、この簡単な方法1つで解決されることもあるのでお困りの方は試してみてください。少しでも参考になれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gempgをインストールしようとするとlibpq-fe.hがないと言われる

アプリ作成コマンドを実行した際のエラーに苦しめられたので後発者のためにメモ書きとして解決策を記しておくことにする。
すぐ本題に入りたい方は’libpq-fe.hをインストールする’項まで飛ぶことを推奨する。

開発環境

windows 10 home
ubuntu 20.04 LTS
ruby 2.7.1
Rails 6.0.3

問題深堀り順

問題の深堀り順としては

①アプリ作成コマンド
rails new (アプリ名) -d pstgresql

にて
pg(1.2.3)のインストール中にエラーが発生し、Bundlerを続行できません。
バンドルする前に、gem install pg -v '1.2.3' --source'https:// ruby​​gems.org / 'が成功することを確認してください。
というエラーがでた。

②エラー文の指示コマンドを実行してみる
gem install pg -v '1.2.3'

すると、どこかに保存されているmkmf.lpgにログが残っているから見ろと指示される。

③mkmf.lpgログを確認する

ログの中身にlibpq-fe.hが見当たらないという旨のエラーがでてることを発見。
これ以上深堀りできないのでlibpq-fe.hが存在しないというのが真の原因と断定。

libpq-fe.hをインストールする

方法①(主が解決した方法)
sudo apt install libpq-dev

主が解決した手順以外にも場合によっては解決するかもしれない方法も載せておく。
あくまでかもしれないなので、解決しなくても許してほしい。
ちなみに主はこれでは解決できなかった。

方法②
Sudo apt-get install libpq-dev
方法③
sudo install postgresql-devel
方法④
sudo install postgresql

解決確認

rails new (アプリ名) -d pstgresql

を実行してもエラーが発生していないことを確認。
問題が解決できたと判断する。
主の場合方法①で解決できた。

最後に

この記事にたどり着きどうしてもわからなかったらこの記事に助けを求めてみてほしい。
おそらくその頃には主もそれなりに知識をつけているはずだろうからきっと助けれるはずだ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails] user_idのwrong number of arguments (given 2, expected 0..1)の解消法

前提

deviseを導入してユーザーと投稿を紐づけるところ
(deviseなくてもいいがcurrent_userは@current_userで定義する必要あり)

やったこと

こちらを参考に**を追加

@gear = Gear.new(
  **gear_params,
  user_id: current_user.id
)

hash key "" is not a Symbolという謎のエラーにより撃沈

gear_paramsメソッドを使わずに全部書いてみた

@gear = Gear.new(
      category: params[:category],
      name: params[:name],
      maker: params[:maker],
      price: params[:price],
      memo: params[:memo],
      user_id: current_user.id
      )

なぜかrollbackされデータベースに保存されず。。
ActiveRecord::RecordInvalid (バリデーションに失敗しました: Userを入力してください
(未解決)

解決方法

完全に分けて書けばハッシュをシンボルにとか考えずに済む

def create
    @gear = Gear.new(
      gear_params
      )
    @gear.user_id = current_user.id
      .
      .
      .
end

参考にさせていただいたサイト

ユーザと紐付けしたモデルから投稿を保存するのに躓いたので。備忘録として

補足

gear_paramsはこう書いています

  private
  def gear_params
    params.require(:gear).permit(:category, :name, :maker, :price, :memo)
  end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails] deviseで追加した:usernameがデータベースに追加されない

問題

  • sign_up画面でユーザーネームを入力しても保存されない
  • rollback transactionとでてなぜかDBに保存できない

前提

  • deviseを導入していて、新規カラムを追加している
    (今回は:usernameカラム)
  • エラーメッセージを日本語化している

やったこと

解決方法

application_controllerに

application_controller
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
  end
end

と記入:ok_hand:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

なぜスクールはRubyを学習させるのか

なぜJavaではなくRubyを推奨するのか

iStock-973074712-490x265.jpg

結論

挫折しにくく比較的理解しやすいから(参考文献豊富)

実際に転職で求められるスキルとは

レバテックでの言語別求人
sub1(1).png
こんな感じでJavaが全体の約35%と高割合を占めていて、PHPと合わせる全体の約50%という結果となっています。
kangaeruhito.png

Rubyの需要・・・・・

ってなる人、分かります。正直Wantedlyや他媒体の求人を見ていてもRubyエンジニアを求めてる企業はかなり少ないです。じゃあなんでスクールは推すのかというと、、
アプリケーションを自力で作りやすいから!!!
これに尽きると思います。Railsを使って便利なgemも使えば簡単に実装できますし、個人スケールで簡単にアプリ作成ができます。

だからこそ企業が見る視点とは

スクール経由の求人企業なら何を学んできたのかを全て知り尽くされています。だからこそ、自発的に学んだ事をアプリに取り入れたり、自己研鑽しているかを重視しているような気がします。(多分)

結論

スクールでは実装に必要最低限の事しか教えてもらえず、あぁ〜もう無理やぁ〜ってなる気持ちも分かりますが、どちらかというとその部分を1番見ているポイントだと思うので最後まで諦めずに自発的に学んで転職・就職を成功させましょう!!!

現場からは以上です!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む