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

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

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

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

RubyGems

RubyGemsはRubyによるプログラミングのためのパッケージマネジメントツールです。ユーザはこれを使用することで、Rubyライブラリのダウンロードやアップデートや、依存関係の自動解決が可能になります。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

4342閲覧

テーブル名に予約語を使ってしまっているとき、factorygirlでエラーになる

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby

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

RubyGems

RubyGemsはRubyによるプログラミングのためのパッケージマネジメントツールです。ユーザはこれを使用することで、Rubyライブラリのダウンロードやアップデートや、依存関係の自動解決が可能になります。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2016/08/17 05:18

編集2016/08/17 06:39

linesテーブルに対して、factorygirlで

FactoryGirl.define do factory :user do association :line #省略 end end
FactoryGirl.define do factory :line do #省略 end end

と定義して、
expect(build(:user)).to be_validをmodelスペックに書いてテストスイートを実行すると

Failure/Error: expect(build(:user)).to be_valid ActiveRecord::RecordInvalid: Validation failed: Line must exist

エラーになってしまいます。
これはlineがSQLで予約語になっているからであると思われるのですが、どのように対処すればよいでしょうか? (user belongs_to line, line has_many usersの関係です)

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

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

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

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

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

guest1213

2016/08/17 06:30

再現しません。 Rails 4.2.5 + factory_girl_rails 4.0 + MySQL 5.5にてrails g model Line name:stringをしてlinesテーブルを作成し、ご質問にある通りのコードを書き、rake db:migrateしてからRAILS_ENV=test rails cでコンソール上からFactoryGirl.create(:line)を実行しましたが、一切のエラーは発生しませんでした。migrate時も、create時もテーブル名はバッククォートで`lines`のように囲まれており、予約語も利用できるようになっています。 他になにか条件はありませんか? または本当に予約語に起因する問題ですか?エラーメッセージを提示いただければ解決に近づくかもしれません。
退会済みユーザー

退会済みユーザー

2016/08/17 06:45

情報提示が少なくてすみません。。上記のようなエラーメッセージでした> <
guest

回答1

0

ベストアンサー

Rails 5.0.0.1にて以下のようにしたところ同じエラーメッセージが出ました。
条件としてはLineクラスが存在しないかつ必須であることです。

Ruby

1class User < ActiveRecord::Base 2 belongs_to :line, required: true 3end

has_manyなど他の関連の場合はわかりません。

テーブル名が予約語になるかどうかは関係ありません。エラーメッセージの通りLineは存在してなければダメ!です。
関連するクラスが存在しないかつ必須である場合にcreate()などを実行するとRails5ではValidation failed: クラス名 must existというエラーメッセージを出力するようです(なおRails4ではActiveRecord::RecordInvalid: Validation failed: Line can't be blankとなるため再現せずに手こずりました)。

Lineクラスを本当に作成していますか?

追記

もうちょっといろいろいじってみましたが、「クラスが存在しないかつ必須」ではなく**「エンティティが存在しないかつ必須」**が正解ですね。belongs_toで自分が属する親がいない状態ってことです。
つまりFactoryGirlで適切に行う場合は、あらかじめ関連先のエンティティをcreateで作っておいたり、質問者様のようにassociationを指定したりで回避できます。私の環境ではassociation指定でFactoryGirlが関連先のエンティティを適切にDBに挿入してくれましたので再現しませんでした。

あまりbelongs_toが必須でなくてもいいというケースはないかと思いますが、belongs_toのオプションとしてoptional: trueを指定すればValidation failedは回避できます。
なおRails5からはbelongs_toの必須か否かがconfig/以下のファイル内にてconfig.active_record.belongs_to_required_by_default = trueと設定されているため、初期値が「必須」となります。よってoptional: trueと指定するようです。

いずれにしろ予約語であるか否かにかかわらず、適切に構成すれば問題なく実行できるはずですが…。

投稿2016/08/17 08:00

編集2016/08/18 01:59
guest1213

総合スコア306

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

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

退会済みユーザー

退会済みユーザー

2016/08/18 08:35 編集

create(:line)は正常に動作、create(:user)は ActiveRecord::RecordInvalid: Validation failed: Line must exist なので、lineが予約語というのは関係ないですね。。すみません。。 associationは指定してあるのですが、相変わらずエラーです。構成もっとちゃんと見てみます
退会済みユーザー

退会済みユーザー

2016/08/18 08:36 編集

今回の原因がわかりました。lineテーブルでもなくuserテーブルでもなく、userがbelongs_toし、lineがhas_manyしていたstationテーブルが問題でした。問題点を明確にしない質問で本当に申し訳ありませんでした。 optional: trueを設定しながら探ったのがきっかけで見つかったので回答者様の指摘が非常に助かりました。ありがとうございました! 以下詳細 usr belongs_to line user belongs_to station station belongs_to line の状況下 create(:user)すると 関連するline, stationが生成される このときstation belongs_to lineより、関連するlineが生成されなくてはならないことになり ActiveRecord::RecordInvalid: Validation failed: Line must exist になっていた。 対応策 Userテーブルのbelongs_to :lineをoptional: trueにし、station factoryに`association :lineを追加した
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問