0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsで多対多のリレーションを作るときにはまったこと

Last updated at Posted at 2019-05-02

概要

Railsで多対多モデルのリレーションを貼る際にハマったことを記載しておきます。

環境

  • Ruby 2.5.1
  • Rails 5.2.3

モデル

下記のようなモデルを作るとします。

                      +------------+
+------------+        | PostTag    |
| Post       |        +------------+        +------------+
+------------+ 1    * | id         |        | Tag        |
| id         |--------| post_id    | *    1 +------------+
| content    |        | tag_id     |--------| id         |
+------------+        +------------+        | name       |
                                            +------------+

ハマった内容

通常はPostからTag(その逆も)を参照できるように以下のようなリレーションを定義すると思います。

class Post < ApplicationRecord
  has_many :post_tags
  has_many :tags, through: :post_tags
end
class PostTag < ApplicationRecord
  belongs_to :post
  belongs_to :tag
end
class Tag < ApplicationRecord
  has_many :post_tags
  has_many :posts, through: :post_tags
end

この際、上記のような記述順ではうまくいきますが、Postモデル、Tagモデルのhas_manyの順番が逆の場合は、上記の環境ではうまくいきませんでした。

class Post < ApplicationRecord
  has_many :tags, through: :post_tags
  has_many :post_tags
end

多対多で検索すると下記のような順番で記述している例もたくさんあるのですが、Rails5になって厳しくなったんでしょうかね。
ActiveRecord::HasManyThroughOrderErrorエラーが出てしまうようです。

[1] pry(main)> Post.find(1).tags
  Post Load (0.4ms)  SELECT  `posts`.* FROM `posts` WHERE `posts`.`id` = 1 LIMIT 1
ActiveRecord::HasManyThroughOrderError: Cannot have a has_many :through association 'Post#tags' which goes through 'Post#post_tags' before the through association is defined.
from /mnt/e/Development/gunplus/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/reflection.rb:943:in `check_validity!'
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?