20200527のRubyに関する記事は19件です。

[Ruby]配列で要素を習得する際の添え字の役割

添え字について、読み流していたのでこの機会にまとめてみました。

配列における添え字の役割

添え字
a = [1,2,3,4,5,6,7]
a[2,5] #=> [3,4,5,6,7]

引数のひとつ目が、位置
引数のふたつ目が、長さを表す。

ちなみに

添え字の代入
a = [1,2,3,4,5,6,7]
a[2,5]= 777
a #=> [1,2,777]

要素の3番目から、5つの要素一括で777に置き換わります。


values_atとlast

こっからは配列のおまけ。

values_at
a = [1,2,3,4,5,6,7]
a.values_at[2,5] #=> [3,6]

a = [1,2,3,4,5,6,7]
a.values_at[2,5,6] #=> [3,6,7]

取得したい要素の数に応じて、添え字を追加できる。

last
a = [1,2,3,4,5,6,7]
a.last  #=> 7

a = [1,2,3,4,5,6,7]
a.last(4)  #=> [4,5,6,7]

配列の最後の要素を取り出すメソッドlastは、引数に0以上の値を渡すと、
その分だけ要素を後ろから取り出します。
最初みたときは、引数に指定した値を後ろから数えて、要素を1つ取得するのかと思っていました。

配列だけ見ても、新たな発見ばかりで面白いですね。
今日はこの辺で。

プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで

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

『オブジェクト指向設計実践ガイド』を読んでいく

決意表明

1か月ちょい~2か月かけて少しずつ読み進めたい。

要点

オブジェクト指向プログラミングの概要・導入

1. オブジェクト指向設計

1.1 設計の賞賛

  • オブジェクト指向設計の手法に従えば、コーディングを楽しくし、かつ最も効率良くソフトウェアを生産できる!
  • オブジェクト指向設計 = 依存関係を管理すること。
    • 部品
      • オブジェクト
    • 相互作用
      • メッセージ
  • 設計の目的は変更コストの削減。

1.2 設計の道具

  • 設計原則『SOLID』
  • デザインパターン『GoF』

1.3 設計の行為

  • BUFD(ウォーターフォール?)とオブジェクト指向設計とでは"設計"の意味が異なる。
    • BUFD
      • 未来の内部動作を特定した、完全な文書化。
    • オブジェクト指向設計
      • 変更を前提とした、小さな領域におけるコード構成。

1.4 オブジェクト指向プログラミングのかんたんな導入

  • 手続き型言語
    • 変数が持つデータ型は一つ。
    • データと振る舞いは別物。
  • オブジェクト指向言語
    • オブジェクトは振る舞いを持つ。
    • いくつもの型(=クラス)を持つ。
      • オブジェクトの振る舞いを予想できる。
  • オブジェクト指向言語は型を拡張できる。よって、オブジェクト指向アプリケーションはプログラマーの扱う特別独自のプログラミング言語となっていく。

クラスに焦点を当てる

2.単一責任のクラスを設計する

  • アプリケーションのモデル化という目標には2つの異なる基準がある。
    • クラスを使い、「いますぐに」求められる動作を行う。
    • 「あとにも」かんたんに変更できるようにする。
      • プログラミングの技術力が如実に現れる部分。

2.1 クラスに属するものを決める

  • TRUEなコードを書くための第一歩は、単一の責任(=最小で有用)を持つよう徹底すること。

2.2 単一の責任を持つクラスを作る

  • すべてのクラスやメソッドは、単一の責任を持つようにする。
    • 単一責任とは?
      • クラスの持つメソッドを質問に言い換えたときに、意味をなす質問になっている。
      • 一文でクラスを説明できる。
        • 「それと」や「または」が含まれない。

2.3 変更を歓迎するコードを書く

  • インスタンス変数やデータ構造は隠蔽する = 振る舞い(メソッド)へと変更する。
    • 予期せぬ変更がコードに影響を与えることを防ぐ。
  • いったんすべてのメソッドを単一責任にしてしまうことで、クラスのスコープが明白になる。

3.依存関係を管理する

オブジェクト中心の設計からメッセージ中心の設計へ

4.柔軟なインターフェースをつくる
5.ダックタイピングでコストを削減する
6.継承によって振る舞いを獲得する
7.モジュールでロールの振る舞いを共有する
8.コンポジションでオブジェクトを組み合わせる

テストの設計

9.費用対効果の高いテストを設計する

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

rails での初めてのページネーション機能の追加

rails での初めてのページネーション機能の追加

参考にした記事(https://qiita.com/residenti/items/1ae1e5ceb59c0729c0b9)

ページネーションとは

長くなってしまったコンテンツを複数のページに分割して情報を読み取ることです。
googleの検索結果などが例に挙げられます。

まずgemのinstall

kaminariというgemを使って実装します。

gemfile
gem'kaminari', '~> 0.17.0'

rails5系ではkaminariのバージョンを上記のように指定しないと動作しないそうです。bundle installします。

コントローラー

topics_controller
 @topics=Topic.page(params[:page]).per(5)

@topics=Topic.all
を上記のように変更しました。perメソッドで1ページに何件まで表示するか決定します。

View

index.html.erb
 <% @topics.each do |a| %>
            問題:<%=a.question %><br><br>
              :<%=a.choice1 %><br>
              :<%=a.choice2 %><br>
              :<%=a.choice3 %><br>
              :<%=a.choice4 %><br>
 <% end %>

<%= paginate @topics %>

<%= paginate @topics %>を書くだけです。
以上でページネーション機能の追加が完了しました。

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

Ruby で始める GraphQL Client

これは何

  • Ruby のコードから GraphQL API を叩く方法を紹介します
    • Ruby のコードで GraphQL API を作る方法は紹介しません

GraphQL とは

GraphQL とは何か、を一言で表現するのは難しいのですが、個人的には「API を表現するプロトコルの一種」というような認識です。
REST API と比較されることが多いです。REST API で

curl http://example.com/users/123/posts/

のようにして叩くところを、GraphQL では

curl http://example.com/graphql -X POST --data '
  {
    user("123") {
      posts {
        title
      }
    }
  }
'

のように叩きます。REST API では /users/ /users/123/ /users/123/posts/ のように様々な URL にリクエストを投げて目的の情報を手に入れますが、GraphQL では 1 つのエンドポイントに様々なクエリを投げ分けることで、必要な情報を全て(不必要な情報は除いて)1 度のリクエストで取得することができます。

GraphQL API の利用方法を学ぶ

取り急ぎ GraphQL API を利用することができればよかったので、私は GraphQL 公式ガイド (https://graphql.org/learn/) の Queries and MutationsSchemas and Types だけを読みました。やや長めのページ 2 つを読むだけで概要が理解できたのでおすすめです。

ただし注意点が 1 つあります。 例として登場する API の意味を深く考えてはいけません。 例えば、冒頭でこんなクエリが登場します。

{
  hero {
    name
  }
}

これに対して、サンプル API はこんなレスポンスを返しています。

{
  "data": {
    "hero": {
      "name": "R2-D2"
    }
  }
}

この例を見たとき、「hero_id を指定したわけでもないのになぜ R2-D2 を返すんだろう?」「hero_id を指定しないときは hero 全てを返す方がいいのでは?」というのが気になって、全体の理解の妨げになってしまいました。実際にはこの API はただのサンプルでしかないので、実用性などは無視して「そういうもの」と思い込む必要があります。単に「任意引数として Episode を 1 つ受け取り、Character を 1 つ返す、hero という Query」があるだけです。

学習用 GraphQL サーバーを立てる

上述した GraphQL 公式ガイドに出てくる謎のスターウォーズ API を再現したものが apollographql/starwars-server です。このあと Ruby から叩くのに使うので、さくっと起動しておきましょう。ブラウザから http://localhost:8080/graphql にアクセスできれば起動成功です。

なお、似た名前のものに graphql/swapi-graphql がありますが、これはより本格的なスターウォーズ API の GraphQL ラッパーなので別物です。気をつけましょう。

Ruby で GraphQL クライアントを使ってみる

Ruby 製の GraphQL Client として github/graphql-client があります。github がオーナーという安心感が凄かったので、ひとまずこれを使おうと思います。

README にも書かれていますが、以下のようにして使います。

require "graphql/client"
require "graphql/client/http"

module SWAPI
  # http アダプターを設定
  HTTP = GraphQL::Client::HTTP.new("http://localhost:8080/graphql")

  # 上記を使って API サーバーから GraphQL Schema 情報を取得
  Schema = GraphQL::Client.load_schema(HTTP)

  # 上記を使ってクライアントを作成
  Client = GraphQL::Client.new(schema: Schema, execute: HTTP)
end

HeroQuery = SWAPI::Client.parse <<~'GRAPHQL'
 {
  hero {
    name
  }
}
GRAPHQL

result = SWAPI::Client.query(HeroQuery)
pp result.to_h

上記では Schema 情報をサーバーから取得していますが、以下のようにしてあらかじめローカルに保存しておき、それをロードする方法もあるそうです。

module SWAPI
  # http アダプターを設定(上例と同じ)
  HTTP = GraphQL::Client::HTTP.new("http://localhost:8080/graphql")

  # ローカルファイルから GraphQL Schema 情報を取得
  Schema = GraphQL::Client.load_schema("path/to/schema.json")

  # 上記を使ってクライアントを作成(上例と同じ)
  Client = GraphQL::Client.new(schema: Schema, execute: HTTP)
end

# API サーバーから GraphQL Schema 情報を取得してローカルファイルに出力
GraphQL::Client.dump_schema(SWAPI::HTTP, "path/to/schema.json")

# ...

注意点

クエリに Operation Name を付ける場合、 SWAPI::Client.query() の引数にモジュール名のように付けて渡す必要があります。

HeroQuery = SWAPI::Client.parse <<~'GRAPHQL'
 # NameOfHero という名前をつけた場合・・・
 query NameOfHero {
  hero {
    name
  }
}
GRAPHQL

# HeroQuery ではなく HeroQuery::NameOfHero を渡す必要がある!
result = SWAPI::Client.query(HeroQuery::NameOfHero)

これを忘れると、 expected definition to be a GraphQL::Client::OperationDefinition but was GraphQL::Language::Nodes::Document (TypeError) というエラーが起きます。

またこのため、必然的に小文字から始まる名前も付けられません(client.rb:241:in 'const_set': wrong constant name ... (NameError) というエラーが起きます)。

この ↓ あたりの issue は全て単にこの仕様を見落としている気がします。

README に明記されていないので私もハマってしまいました・・・(コントリビュートチャンス?)

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

Hello RSpec

新人のRailsエンジニアです。
RailsのTestをするにあたってRSpecを学んだのでまとめてみました。
100日後に1人前になるエンジニアを連載中です。本日は7日目
ちなみにMinitestとRSpecの比較についてはこちら

RSpecとは

RubyやRuby on Railsで作ったクラスやメソッドをテストするためのドメイン特化言語 (DSL)を使ったフレームワーク。
つまりは、テスト専用のプログラム言語とも言えます。

FactoryBot

テスト用のデータの作成をサポートするgem
FactoryBotを利用するとテスト用のデータを簡単に準備できる
Rails標準ではFixtureという仕組みもありますが、
こちらよりもデータの状態やデータ間の関係性を掴みやすい。
ということで今回はこちらも使用。

Capybara

WebアプリケーションのE2E(End-to-End)テスト用フレームワーク。
RSpecなどと組み合わせて使います。Webアプリケーションのブラウザ操作をシュミレーションできる。

RSpecの基本形

RSpecの記述の基本形としては以下の様な形です。

describe [仕様を記述する対象(テスト対象)], type[specの種類] do
  context[ある状況] do
    before do
      [事前準備]
    end
    it[仕様の内容(期待の概要)] do
      [期待する動作]
    end
  end
end

これだけみてもなかなかわからないので分割してみていきます。

describe

describe [仕様を記述する対象(テスト対象)], type[specの種類] do

end

describeには、何について仕様を記述しようとしているのかを書きます。
例えばsystemテストをプロフィール表示機能について仕様を書きたいのであれば

describe 'プロフィール表示機能', type: :system do

と言った具合ですね。

context

こちらはテストの内容を状況、状態のバリエーションごとに分類するために利用します。
例えばユーザーの入力内容が正しいか間違っているか、ユーザーがログインしているか否かなどを
contextに記述していきます。

before

beforeはその領域全体の前提条件を実現するためのコードを記述している
以下のだとプロフィールを表示するための前提条件。
この場合だとログインしていることが前提条件になっている

context 'ユーザーがログインしているとき' do
  before do
    visit login_path
    fill_in 'メールアドレス', with: 'email@example.com'
    fill_in 'パスワード', with: 'password'
    click_button 'ログイン'
  end
end

it

最後のitは期待する動作と文章をブロック内のコードで記述します
expect(page).to have_content 'hoge'
上の記述は画面に"hoge"という内容があるよね??
っていう内容になっています。
expect to have contentなので英語のままといえばそれまでですが。

#プロフィール画面に'ユーザーのプロフィール'って内容があるよね??
it 'ユーザーのプロフィールが表示される' do
  expect(page).to have_content 'ユーザーのプロフィール'
end

以上まとめてみると

describe 'プロフィール表示機能', type: :system do
  context 'ユーザーがログインしているとき' do
    before do
      visit login_path
      fill_in 'メールアドレス', with: 'email@example.com'
      fill_in 'パスワード', with: 'password'
      click_button 'ログイン'
    end
    it 'ユーザーのプロフィールが表示される' do
      expect(page).to have_content 'ユーザーのプロフィール'
    end
  end
end

こう言った形でRSpecの基本形が成り立っています。
いきなり全部理解しようとするとつらいけど、分割してみるとなんとかなりそう。

今回は基本形をどう見るかという点でまとめてみました。
実際はもっとネストがあって、込み入っている様に見えますが、
まずは基本形をおさえてRSpecの理解を深めていきたいですね。

本日は以上です
1人前のエンジニアになるまであと93日

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

Active Record、複雑なクエリ

Active Recordでちょっと複雑な問い合わせを書いた時に、忘れないようにメモとして追記していきます。

関連テーブルのレコード数でソート

class PLine < ApplicationRecord
  has_many :likes, dependent: :destroy
end

class Like < ApplicationRecord
  belongs_to :p_line
end
@p_lines = PLine.select('p_lines.*', 'count(likes.id) AS favs')
                .left_joins(:likes)
                .group('p_lines.id')
                .order('favs desc')
<% @p_lines.each do |p_line| %>
  <p><%= p_line.p_line %></p>
  <p><%= p_line.favs %> points</p>
<% end %>

関連カラムが複数あって、変数の値がどちらかに一致する。関連カラムをすべてincludeしたい。

class Mc < ApplicationRecord
  has_many :videos
end

class Video < ApplicationRecord
  belongs_to :mc1, class_name: 'Mc'
  belongs_to :mc2, class_name: 'Mc'
end
@videos = Video.includes(:mc1, :mc2).where(mc1_id: @mc)
               .or(Video.includes(:mc1, :mc2).where(mc2_id: @mc))
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby : Nokogiriが自分でエンコーディングを参照しに行く場所を調べてみた

はじめに

こちらの記事で、Nokogiriはエンコーディング指定がnilだったときに、パース元のhtmlのmeta要素のcharsetを見に行くと結論づけました。
今回は結論が本当にあっているか確かめるために、公式ドキュメントを追ってみた話です。

公式ドキュメントを追ってみる

Nokogiri公式ドキュメント
今回はこちらの公式ドキュメントを追っていきます。もちろん英語です。
普段自分は英語の公式ドキュメントは避けがちなのですが、決心して見に行ってみます。英語は読めなくてもコードなら読めます。多分。

Nokogiri::HTML::Documentクラス

普通Nokogiriを使ってパースするときにはNokogiri::HTML.parse(html)のように書いているのですが、正式にはNokogiri::HTML::Documentクラスのようです。
Documentクラス欄を開いて.parseメソッドを探し、「view source」でソースを表示してみます。

以下ソース

lib/nokogiri/html/document.rb
def parse string_or_io, url = nil, encoding = nil, options = XML::ParseOptions::DEFAULT_HTML

  options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
  # Give the options to the user
  yield options if block_given?

  if string_or_io.respond_to?(:encoding)
    unless string_or_io.encoding.name == "ASCII-8BIT"
      encoding ||= string_or_io.encoding.name
    end
  end

  if string_or_io.respond_to?(:read)
    url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
    unless encoding
      # Libxml2's parser has poor support for encoding
      # detection.  First, it does not recognize the HTML5
      # style meta charset declaration.  Secondly, even if it
      # successfully detects an encoding hint, it does not
      # re-decode or re-parse the preceding part which may be
      # garbled.
      #
      # EncodingReader aims to perform advanced encoding
      # detection beyond what Libxml2 does, and to emulate
      # rewinding of a stream and make Libxml2 redo parsing
      # from the start when an encoding hint is found.
      string_or_io = EncodingReader.new(string_or_io)
      begin
        return read_io(string_or_io, url, encoding, options.to_i)
      rescue EncodingFound => e
        encoding = e.found_encoding
      end
    end
    return read_io(string_or_io, url, encoding, options.to_i)
  end

  # read_memory pukes on empty docs
  if string_or_io.nil? or string_or_io.empty?
    return encoding ? new.tap { |i| i.encoding = encoding } : new
  end

  encoding ||= EncodingReader.detect_encoding(string_or_io)

  read_memory(string_or_io, url, encoding, options.to_i)
end

まずここに注目してみます

lib/nokogiri/html/document.rb
  if string_or_io.respond_to?(:encoding)
    unless string_or_io.encoding.name == "ASCII-8BIT"
      encoding ||= string_or_io.encoding.name
    end
  end

string_or_ioは普段自分がhtmlを指定している変数です。
解釈して見るに、string_or_ioencodingメソッドを持っており、そのエンコーディング名がASCII-8BITでなく、encoding引数が定義されていなかったら、encodingstring_or_ioのエンコーディング名とする、のようです。

なるほど!だからhtmlをバイナリモードで開かなかった場合には、htmlの開き方(エンコーディング)に依存してしまうので、パース後に文字化けが発生してしまうことがあるということだったんですね!

ではファイルをバイナリモードで開き、かつencoding引数がnilのときにはどうなるのか。
今度はここに注目してみます。

lib/nokogiri/html/document.rb
encoding ||= EncodingReader.detect_encoding(string_or_io)

encoding引数が定義されていなかったら、EncodingReader.detect_encodingメソッドを使うとあります。
おとなしくドキュメントのEncodingReader.detect_encodingメソッドを見に行きます。

先ほどと同じようにソースを表示します。
以下ソース

lib/nokogiri/html/document.rb
def self.detect_encoding(chunk)
  if Nokogiri.jruby? && EncodingReader.is_jruby_without_fix?
    return EncodingReader.detect_encoding_for_jruby_without_fix(chunk)
  end
  m = chunk.match(/\A(<\?xml[ \t\r\n]+[^>]*>)/) and
    return Nokogiri.XML(m[1]).encoding

  if Nokogiri.jruby?
    m = chunk.match(/(<meta\s)(.*)(charset\s*=\s*([\w-]+))(.*)/i) and
      return m[4]
    catch(:encoding_found) {
      Nokogiri::HTML::SAX::Parser.new(JumpSAXHandler.new(:encoding_found)).parse(chunk)
      nil
    }
  else
    handler = SAXHandler.new
    parser = Nokogiri::HTML::SAX::PushParser.new(handler)
    parser << chunk rescue Nokogiri::SyntaxError
    handler.encoding
  end
end

メソッド引数のchunkに、今回はstring_or_io、つまり普段自分がhtmlとしているものが入ります。

見慣れないメソッドが多いのでぱっと正確な意味がとれないですが、2番目のifブロックにmetaのcharsetを参照しているような記述がありませんか???
returnで値を返しているようですし、この箇所が非常に怪しい感じがします。

さいごに

まだソースの細かい箇所が把握できていませんが、自分の求める答えにぐっと近づけた気がします。
ソースの詳細がわかれば、また別記事でまとめようと思います。

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

"ExecJS::RuntimeError"

起動はするのに、、、

railsにて、初めの段階でハマったのでメモメモ。

エラー内容

ExecJS::RuntimeError

バージョン

Rails 5.2.4
ruby 2.5.1

解決策

Gemfile

gem 'mini_racer', platforms: :ruby

上記のコメントアウトを外してあげて、ターミナルで[bundle install]してあげれば、完了。

参考URL

ExecJS::RuntimeError(2019年版)
https://github.com/railsgirls-jp/coach.info/issues/27

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

【Ruby on Rails+devise+sendgrid】Signupでのメール送信機能を使う手順解説

環境

ruby 2.6.4

Rails 5.2.4.2

rbenv 1.1.2

mysql2 0.5.3

やりたいこと

コピペのみでメール送信機能を実装できる手順を紹介します

元ネタは
【Rails5.2/sendgrid】超簡単!Signupのメール送信を本番環境で使うための手順(Heroku)Part1です

sendgridを使って簡単に実装していきます

sendgrid導入手順

1. Herokuにプロジェクトを作成

$ heroku create

2. プロジェクト名を変更

$ heroku rename 変更後のプロジェクト名

3. プッシュ

$ git push heroku master

4. sendgridコマンドを通す

$ heroku addons:create sendgrid:starter

5. sendgridページからAPIキーを作成&コピー

sendgrid_api_key.png

6. APIキーを設定

$ heroku config:set SENDGRID_USERNAME=apikey
$ heroku config:set SENDGRID_PASSWORD=取得したAPIキー

7. environment.rbを修正

config/environment.rb
# Load the Rails application.
require_relative 'application'

# Initialize the Rails application.
Rails.application.initialize!

ActionMailer::Base.smtp_settings = {
  :address => 'smtp.sendgrid.net',
  :port => '587',
  :authentication => :plain,
  :user_name => ENV['SENDGRID_USERNAME'],
  :password => ENV['SENDGRID_PASSWORD'],
  :domain => 'heroku.com',
  :enable_starttls_auto => true
}

8. development.rbに下の2行を追加

config/environments/development.rb
  config.action_mailer.delivery_method = :test

  config.action_mailer.default_url_options = { :host => 'http://previewurlforyourapp'}

9. rails s

$ rails s

10. application.html.erbを修正

app/views/layouts/application.html.erb
   <div class="navbar navbar-default navbar-static-top">
      <div class="container">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">PhotoApp</a>
        <div class="navbar-collapse collapse navbar-responsive-collapse">
          <ul class="nav navbar-nav">
            <li><%= link_to "Link1", "/path1"  %></li>
            <li><%= link_to "Link2", "/path2"  %></li>
            <li><%= link_to "Link3", "/path3"  %></li>
          </ul>
          <ul class="nav navbar-right col-md-4">
            <% if current_user %>
            <li class="col-md-8 user-name">
              <%= link_to ('<i class="fa fa-user"></i> ' + truncate(current_user.email, length: 25)).html_safe,
                                                            edit_user_registration_path, title: 'Edit Profile' %>
            </li>
            <li class="col-md-1"> </li>
            <li class="col-md-3 logout"><%= link_to('Logout', destroy_user_session_path,
                                  class: 'btn btn-xs btn-danger', title: 'Logout', :method => :delete) %></li>
            <% else %>
            <li class="col-md-4 pull-right">
              <%= link_to('Sign In', new_user_session_path, class: 'btn btn-primary', title: 'Sign In') %>
            </li>
            <% end %>
          </ul>
        </div>
      </div>
    </div>

11. app/assets/stylesheets/custom.css.scssを作成&修正

app/assets/stylesheets/custom.css.scss
.user-name {
  padding: 0 !important ;
  padding-left: 5px;
  padding-top: 15px !important;
  text-align: center;

  a {
        color: black !important;
        margin: 0 !important;
        padding: 5px!important;
  }

  a:hover, a:focus {
     color: #000 !important;
  }
}

.logout {
  padding-left: 0;
}

.nav.navbar-right {
  padding-bottom: 10px;
  padding-top: 5px;
}

.nav.navbar-nav {
  .navbar-link {
    border-radius: 5px;
    color: #fff;
    margin-top: 15px;
    padding: 8px;
  }

  .navbar-link:focus, .navbar-link:hover {
    background: #3071a9;
    color: #fff;
  }

  li a {
    margin-right: 5px;
  }
}

.nav.navbar-right li {
  .btn {
    color: #fff !important;
    margin-top: 5%;
  }

  .btn-danger:hover, .btn-danger:focus {
    background-color: darken(#d9534f,20%) !important;
  }

  .btn-primary:hover, .btn-primary:focus {
    background-color: darken(#428bca,20%) !important;
  }
}

.btn-primary:visited, .btn-danger:visited {
  color: #fff;
}

参考文献

2つともRails初心者にとても詳しく書かれているので一度目を通しておくことをおすすめします
特に本番環境でsendgridを使いたい方はとても参考になります

【Rails5.2/sendgrid】超簡単!Signupのメール送信を本番環境で使うための手順(Heroku)Part1
https://www.twinzlabo.com/rails_sendgrid_easy/
【Rails5.2/sendgrid】超簡単!Signupのメール送信を本番環境で使うための手順(Heroku)Part2
https://www.twinzlabo.com/rails_sendgrid_easy_2/

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

Ruby と Python で解く AtCoder ABC130 D 累積和 二分探索

はじめに

AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

今回のお題

AtCoder Beginner Contest D - Enough Array
Difficulty: 859

今回のテーマ、累積和 + 二分探索

問題文(条件)連続部分列に含まれる全ての要素の値の和は、K 以上である。より累積和を使用することが分かりますが、1≦N≦100_000ですので2重にループを回すとTLEになります。
そこで、累積和は単調増加ですので、計算量を抑えるために二分探索も併用します。

Ruby

ruby.rb
n, k = gets.split.map(&:to_i)
a = gets.split.map(&:to_i)
acc = 0
x = [0] + a.map{|v| acc += v}
cnt = 0
x.each do |y|
  j = x.bsearch_index{|z| z - y >= k}
  if j == nil
    break
  else
    cnt += n - j + 1
  end
end
puts cnt
accumulate.rb
acc = 0
x = [0] + a.map{|v| acc += v}

累積和はここで計算しています。
追記
コメントでいただいたコードに修正しました。

bsearch.rb
  j = x.bsearch_index{|z| z - y >= k}

二分探索ですが、C++ でいうところのlower_boundが、Ruby ではbsearch若しくはbsearch_indexになります。

Python

python.py
from sys import stdin

def main():
    import bisect
    import itertools

    input = stdin.readline
    n, k = map(int, input().split())
    a = list(map(int, input().split()))
    x = [0] + list(itertools.accumulate(a))
    cnt = 0
    for z in x:
        j = bisect.bisect_left(x, k + z)
        if j <= n:
            cnt += n - j + 1
    print(cnt)
main()
accumulate.py
    x = [0] + list(itertools.accumulate(a))

Python では、累積和を求めるaccumulateという関数があります。

bisect.py
        j = bisect.bisect_left(x, k + z)

二分探索ですが、bisect若しくはbisect_left bisect_rightを使用します。
探索する数値が配列に含まれる場合、bisectはその数値の右側、bisect_leftは左側の位置を返します。

for.py
    for z in x:
    for i in range(n):

range()でループを回すとTLEしました。

Ruby Python
コード長 (Byte) 238 377
実行時間 (ms) 165 101
メモリ (KB) 11780 14196

まとめ

  • ABC 130 D を解いた
  • Ruby に詳しくなった
  • Python に詳しくなった

参照したサイト

instance method Array#bsearch
すごいぞitertoolsくん
bisect --- 配列二分法アルゴリズム

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

% rails db:createするとmimemagic に起因するLoadErrorががが


% rails db:create
rails aborted!
LoadError: cannot load such file -- mimemagic
/projects/〜〜〜/config/application.rb:7:in `<main>'
/projects/〜〜〜/Rakefile:4:in `<main>'
bin/rails:4:in `<main>'

git hubからとあるファイルをcloneしdb:createをした際に生じたエラー

まいむまじっく.......???
なかなかマイナーなファイルが原因を引き起こしてるっぽいけども・・・

ひとりでは解決困難!!先輩の力を借りてる最中、Qiitaをみてみるとこんな記事が

a.com/zQmjRAb73seN5RM/items/5fa74d2a4d346cdd386e

バージョンの問題っぽい・・・?
その通りにコマンドを実行してみた

$gem list 〇〇 
//〇〇には該当ファイルを入れる(今回だとmimemagic)

結果は......

mimemagic (default: 0.3.5, 0.3.4, 0.3.3)

ではどんなファイルがあるのかを確認してみる

find ~/.rbenv -type f | grep 〇〇
//〇〇には該当ファイルを入れる(今回だとmimemagic)

結果は......

(一部抜粋)
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/test/files/image.png
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/test/files/application.zip
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/CHANGELOG.md
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/script/freedesktop.org.xml
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/script/generate-mime.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/README.md
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/Rakefile
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/mimemagic.gemspec
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/.gitignore
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic/tables.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic/version.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic/overlay.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/Gemfile
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/.travis.yml
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/.yardopts
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/LICENSE
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/mimemagic_test.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{gdocs}.sheet
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.x-tar
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.gzip
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.x-bzip
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{msoffice}.sheet
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/image.jpeg
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.x-ruby
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/image.png
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{rubyxl}.sheet
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/files/application.zip
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/CHANGELOG.md
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/script/freedesktop.org.xml
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/script/generate-mime.rb/Users/tech-camp/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/test/files/image.png
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/test/files/application.zip
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/CHANGELOG.md/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/script/freedesktop.org.xml
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/script/generate-mime.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/README.md
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/Rakefile
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/mimemagic.gemspec
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/.gitignore
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic/tables.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic/version.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic/overlay.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/lib/mimemagic.rb
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/Gemfile
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.3/.travis.yml
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/.yardopts
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/LICENSE
/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mimemagic-0.3.4/test/mimemagic_test.rb

みてみると 0.3.3 0.3.4のファイルはあることになっているが、0.3.5がないとのこと
ここが食い違っているから生じたエラー is 濃厚......
この食い違いを解決するには、

% gem install mimemagic -v 0.3.5

結果

Successfully installed mimemagic-0.3.5

そして畳みかけます

% bundle install    
% rails db:create

成功!!!!!!!

LoadErrorのさいはぜひ参考にしてみてください!

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

RSpec RequestSpecでsessionを利用する

Rspec request specでセッションの読み込み、書き込みを実現してみる

今回はActionDispatch::Requestのsessionメソッドを上書きする形で対応します

allow_any_instance_of(ActionDispatch::Request).to receive(:session).and_return({})

事前にセッションを書き込む方法

rails_helper.rb に上記のsessionメソッド上書きを実装します

rails_helper.rb
RSpec.configure do |config|
  # ...

  # テストケース共通の事前処理
  config.before(:each) do

    # let(:rspec_session) で指定された値を セッションの初期値とします
    session = defined?(rspec_session) ? rspec_session : {}

    # destroyメソッドを実行してもエラーにならないようにします(必要であれば)
    session.class_eval { def destroy; nil; end } 

    # sessionメソッドを上書き
    allow_any_instance_of(ActionDispatch::Request).to receive(:session).and_return(session)
  end
end

以下のように テストコード内の変数でセッションの初期値を設定できます

let(:rspec_session) { { user_id: 1 } }

事前にセッションを書き込む&実行後のセッションを取得する方法

config.add_setting() を使用し、session変数をグローバルで扱えるようにします

上記の rails_helper.rb に更に追記します

rails_helper.rb
RSpec.configure do |config|
  # ...

  # テストケース共通の事前処理
  config.before(:each) do

    # let(:rspec_session) で指定された値を セッションの初期値とします
    session = defined?(rspec_session) ? rspec_session : {}

    # destroyメソッドを実行してもエラーにならないようにします(必要であれば)
    session.class_eval { def destroy; nil; end }

    # 追記 実行後のセッションを取得できるようにする
    config.add_setting(:session, :default => session)

    # 変更 sessionメソッドをRSpec.configuration.sessionで上書き
    allow_any_instance_of(ActionDispatch::Request).to receive(:session).and_return(RSpec.configuration.session)
  end
end

テスト実施後に RSpec.configuration.session を取得することで、実行後のセッションを確認できます

expect(RSpec.configuration.session[:user_id]).to eq 1

参考にしました

Method: RSpec::Core::Configuration#add_setting

いいね!と思ったら LGTMお願いします?

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

railsでGoogleMapAPIの導入

このページのコードでできること

・自分のrailsプロジェクトにGoogleMapを埋め込み、表示させる。
・ページを開いたら地図と、初期値のマーカーを表示させる。
・inputボックスと検索ボタンを用意。
・inputボックスに検索したい場所を入力し、検索ボタンを押すことでその場所の地図を表示。

Maps JavaScript API & Geocoding APIの取得

これら記事にお世話になりました。(参考文献より)

コードを書く前に
Google Maps API を使ってみた
Google MAP 名称から場所を検索・特定する
オリジナルアプリ作成 〜RailsでGoogleMap利用検証〜

コード

postsに記述するとします。
@post.locationは一例です。ご自身のアプリケーションにふさわしい初期値を入れてください。

posts/index.html.erb
<div id='target'></div>

<div class='map-btn'>
<input id="address" type="textbox" value="<%= @post.location %>">
<input type="button" value="検索" onclick="codeAddress()">
<div>

<script src="https://maps.googleapis.com/maps/api/js?key=自分のAPIキー&callback=initMap" async defer></script>

style.scss
#target {
  height: 300px;
  width: 300px;
}

Javascriptの記述

post.js
let map
let geocoder
let centerp = {lat: 33.60639, lng: 130.41806}

function initMap(){
  geocoder = new google.maps.Geocoder()

  map = new google.maps.Map(document.getElementById('target'), {
    center: centerp,
    zoom: 12,
  });

  marker = new google.maps.Marker({
    position: centerp,
    map: map
  });
}

function codeAddress(){
  let inputAddress = document.getElementById('address').value;

  geocoder.geocode( { 'address': inputAddress}, function(results, status) {
    if (status == 'OK') {
      map.setCenter(results[0].geometry.location);
      var marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location
      });
    } else {
      alert('該当する結果がありませんでした:' + status);
    }
  });   
}

参考文献

大変お世話になりました。感謝。

コードを書く前に
[https://qiita.com/nagaseToya/items/e49977efb686ed05eadb]

Google Maps API を使ってみた
[https://qiita.com/Haruka-Ogawa/items/997401a2edcd20e61037]

Google MAP 名称から場所を検索・特定する
[https://qiita.com/yoshi_yast/items/521c1f36306a180f45dd]

オリジナルアプリ作成 〜RailsでGoogleMap利用検証〜
[https://note.com/daddy0055/n/nddbe8da38bbc]

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

MySQLのモードに関して

自分のローカルで設定されているモード

$ mysql --version
mysql  Ver 14.14 Distrib 5.7.29, for osx10.15 (x86_64) using  EditLine wrapper
$ mysql -uroot -p
mysql> select @@global.sql_mode;
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| @@global.sql_mode                                                                                                                                    |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
  • STRICT_TRANS_TABLES
  • STRICT_ALL_TABLES
  • NO_ZERO_IN_DATE
  • NO_ZERO_DATE
  • ERROR_FOR_DIVISION_BY_ZERO
  • NO_AUTO_CREATE_USER
  • NO_ENGINE_SUBSTITUTION

なお、これは紛れもなく、TRADITIONALモードである。TRADITIONALモードとは上の7つのモードが全て有効になっている状態を言う組み合わせモードなのだ。

STRICTモード

STRICT_TRANS_TABLESモードとSTRICT_ALL_TABLESモードのいずれかが有効な場合、それはSTRICTモードである。

  • トランザクションストレージエンジン

    • 不正な値が挿入されようとした場合、エラーを発し(不良データ値は調整されない)、ロールバックする
  • 非トランザクションストレージエンジン

    • STRICT_TRANS_TABLES
      • 1行目で不良データを挿入しようとした時はエラーを起こし終了
      • 2行目以降で不良データを挿入しようとした時は不良データを調整して挿入し、(エラーではなく)警告を発する
    • STRICT_ALL_TABLES
      • 1行目でも2行目以降で不良データを挿入しようとした時はエラーを起こし終了(部分更新が行われる)

参考

というかもはや以下の要約
MySQLのSQLモードをstrictモードで設定する。

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

【Ruby】僕がしていたモジュールにしていた勘違い【初学者】

Rubyの勉強中の僕がしていたモジュールに関する勘違いを勝手に紹介します。

⬇勘違いしていたときのコード⬇
ruby_module1.png
⬇正解コード(間違いがあればご指摘いただけると幸いです)⬇
ruby_module2.png
違いとしてはモジュールの記述されている「thinkable.rb」に
require "./human"
があるかないかの違いです。
実際、あってもなくても実行結果に変化はありませんがこの記述は不要なものなので無いほうが良いでしょう。

そもそもなぜこのような勘違いをしていたのか

なぜ僕がこのような勘違いをしていたのかと言うとモジュールというものをしっかり理解できていなかったということがありますがモジュール内で「human.rb」で定義されている「self.hobby」を利用するのだから「human.rb」を「tahinkable.rb」で読み込まなきゃいけないんじゃね。というように思っていたからです。

require "./human"
の記述があってもなくても結果は変わらなかったので私が受講中のTeacAcadmyでメンターの方に聞いてみると親切に回答していただけました。

答えとしては

module は Mix-in して初めて動作する
「self.hobby」も読み込まれた先の「self.hobby」を参照するための記述のため、「./human」を読み込んでいなくても、「Human」に読み込んだ時に動作する

というものでした。
つまりモジュールはクラスで読み込まれた時に初めて動作するということだったんですね。

一つ勘違いをなくすことができました。

以上、初学者の私がしていた勘違いを勝手に紹介させていただきました。

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

こんなソースコードはイヤだ-クォーテーションはシングルなのダブルなの?

プログラムのソースコードのより良い書き方をまとめていこうと思います。

クォーテーションはシングルなのダブルなの?

sample.sh
  name="Taro"
  age=19
  country='Japan'
  greeting="I am $name. I am ${age} years old. I live in $country"
  echo $greeting

どのようにリファクタリングできるのか

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

ruby subメソッドで使用した正規表現について

address="都道府県,市区町村,番地,建物名部屋番号"
という変数があり、ここから、番地を取得したいとします。
結論からいうと、

address.split(",")[2]

ですが、
正規表現でチャレンジしました。

まずはsubで、戦闘の「都道府県,」を消して、それを2回繰り返そうと思いました。
のこった「番地,建物名部屋番号」から、「,」以降を消して終わりです。

まずは1回だけのバージョンでテスト
address.sub(/.+,/,'')
「都道府県,」のみが消える予定です。

結果
"建物名部屋番号"
となっちゃいました。

/.+,/の部分が「都道府県,」になるだろうと予測したのですが、
「都道府県,市区町村,番地,」になっちゃいます。

試しに
address.sub(/,/,'')
としてみると
「都道府県市区町村,番地,建物名部屋番号」
となり、最初の1個目をちゃんとけしてくれます。

なぜに???

・・・・・
まぁ番地のみ取得という問題は解決しているので
そういうもんだろうと今は割り切って次に進みます。
まだまだ、勉強中なもので、、、
今後勉強していけば、この疑問も晴れるかも、、、
よかったら誰か教えてTT

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

Rubyの文字列とシンボルの違い【初学者】

初投稿です。

誤りがあればご指摘お願いします。

文字列とシンボルの違い

文字列とシンボルは見た目は似ていますが別物。

どう違うかと言うと与えられるオブジェクトIDが違います。

文字列の場合、同じ文字列を2つ用意した場合でも与えられるオブジェクトIDは異なるものになりますが、シンボルの場合、同じ文字列を2つ用意した場合でも同じオブジェクトIDが与えられます。

具体的に見てみるとこんな感じです。
Ruby_symbol1.png
実行結果
Ruby_symbol2.png
オブジェクトに対してオブジェクトIDを表示してくれるメソッドの「object_id」を利用してオブジェクトIDを表示するとこのようになります。

上2つの文字列("JUN")に対するオブジェクトIDはそれぞれ違ったものが表示されていますが、シンボル(:JUN)に対するオブジェクトIDは同じものが表示されています。

ちなみに
Ruby_symbol3.png
Ruby_symbol4.png
当然のことですがもう一度実行すると1回めと比べて文字列に対して与えられるオブジェクトIDは異なりますが、シンボルのオブジェクトIDは1回目と同じものです。

さらに1回目の実行時はすべて大文字(:JUN)で表示しましたが小文字で(:jun)で表記した場合は大文字のときとは違ったオブジェクトIDが与えられます。

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

【Ruby/Rails】破壊的メソッドを利用した時にNoMethodErrorが出た時に対処したこと

起きたエラー

filter!の類の破壊的メソッドを使った時にNoMethodErrorが出ました。

対処出来たのでメモがてら残します。(間違ったら優しく教えてください…。)

再現する方法

object_controller.rb
def index
  @object = Object.all
  @object.filter! do |o|
    o.id != 1
  end
end

※命名適当なのは勘弁してください。

オブジェクトをallとかで配列で取得した時に、filterみたいな非破壊的メソッドは使えたのですが、filter!みたいな破壊的メソッドで条件に一致しないオブジェクトを弾いた配列を作ろうとしてました。

ですが、一番最初の見出しの通りNoMethodErrorを吐きました。

対処した方法

object_controller.rb
def index
  @object = Object.all
  @object.to_a.filter! do |o|
    o.id != 1
  end
end

to_aでオブジェクトを配列に変換するとNoMethodErrorを吐かなくなりました。

理由とかは調べて見つけたら追記します。

一旦、忘れないようにメモがてらに残します。(念押し)

既に理由とか知っている人がいて、それくらい当然っしょみたいなノリでしたら、何かにリンクをペタッと貼ってもらえる紳士な方がいてくれると最高に嬉しいです…。

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