質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

解決済

1回答

685閲覧

Active Recordのメソッドをmodule化したい

b_kazu

総合スコア26

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

0グッド

0クリップ

投稿2020/11/16 03:46

複数のデータベースからデータを引き出しています。
どのデータベースもテーブルの構成は同じです。
共通のメソッドをmoduleで1つにまとめたいのですがうまくいきません。
Active Recordのクラスメソッドをmoduleの中でどう定義すればいいのか思いつきません。

環境
macOS 10.15.7
Ruby 2.7.2
Active Record 6.0.3
PostgreSQL 13.0

現在、動いているコード

tokyo.rb

ruby

1class Tokyo < ActiveRecord::Base 2 establish_connection( 3 adapter: "postgresql", 4 host: "", 5 username: "myname", 6 password: "", 7 database: "tokyo" 8 ) 9 10 def name 11 users = Tokyo.all 12 users.each do |user| 13 if user['id'] == 1 14 puts user['id'] 15 puts user['name'] 16 puts user['address'] 17 end 18 end 19 end 20end

osaka.rb

ruby

1class Osaka < ActiveRecord::Base 2 establish_connection( 3 adapter: "postgresql", 4 host: "", 5 username: "myname", 6 password: "", 7 database: "osaka" 8 ) 9 10 def name 11 users = Osaka.all 12 users.each do |user| 13 if user['id'] == 1 14 puts user['id'] 15 puts user['name'] 16 puts user['address'] 17 end 18 end 19 end 20end

main.rb

ruby

1require 'active_record' 2require_relative 'tokyo' 3require_relative 'osaka' 4 5Tokyo.new.name 6Osaka.new.name

上のコードのようにnameメソッドをモデルごとに定義すれば動くのですが、moduleでまとめたいと思っています。

エラーになるコード

name.rb

ruby

1module Name 2 def name 3 users = self.all 4 users.each do |user| 5 if user['id'] == 1 6 puts user['id'] 7 puts user['name'] 8 puts user['address'] 9 end 10 end 11 end 12end

tokyo.rb

ruby

1require_relative 'name' 2 3class Tokyo < ActiveRecord::Base 4 establish_connection( 5 adapter: "postgresql", 6 host: "", 7 username: "myname", 8 password: "", 9 database: "tokyo" 10 ) 11 12 include Name 13end

main.rb

ruby

1require 'active_record' 2require_relative 'tokyo' 3 4Tokyo.new.name

エラー内容

ruby main.rb #=> `method_missing': undefined method `all' for #<*************> (NoMethodError)

mdule内をdef self.nameにしてmain.rbをTokyo.nameにするとなにも反応しません。

解決方法があればよろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/11/16 03:54

列名にnameがある以上、ActiveRecordが列へのアクセス用に自動でnameメソッドを立てるので、それを上書きしてしまうのは良くないと思いますが、名前は変更できますでしょうか?
b_kazu

2020/11/16 04:02

メソッド名は変更可能です。
guest

回答1

0

ベストアンサー

nameメソッド内でのselfは、インスタンスを指しますので、クラスメソッドにアクセスしたい場合はself.class.allのようにする必要があります。

投稿2020/11/16 03:55

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

b_kazu

2020/11/16 04:04

希望どおり動作しました。ありがとうございました。
b_kazu

2020/11/17 23:49

メソッド内の`self`はインスタンス自身。なので`#class`を使って`include`先のクラスが呼び出せるわけですね。今回の例だと`self.class.all`が`Tokyo.all`と同じになる。`self`の理解が曖昧だったのと`#class`を使う発想がありませんでした。勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問