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

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

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

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

Ruby on Rails

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

4750閲覧

【Rails】多対多の関係において、親モデルのデータ取得が出来ないです。お気に入り機能実装で躓いています。

jusco

総合スコア80

Ruby

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

Ruby on Rails

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

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

1クリップ

投稿2015/07/31 10:54

編集2015/07/31 13:32

Shop_basicモデルと1対1関係にあるShopモデルが投稿したPostモデルを、Userモデルはお気に入りに登録できる、という機能を実装しています。

そこで、実際にお気に入りに登録する機能自体は実装できたのですが、
Viewにてデータを取得して表示させる際に、
post.shop.shop_basic.id
を取得しようとすると
【undefined method `shop_basic' for ...】
とエラーが出てしまいます。
以下のような関係を持つ複数のモデルを用いています。

問題のViewは以下のものです。

Ruby

1#app/views/users/favorite.html.erb 2<% @feed_posts.each do |pt| %> 3 4 <p><%= pt.post_title %></p> 5 <p><%= pt.shop.shop_basic.id %></p> 6 7<% end %>

Usersコントローラーのfavoriteは以下の様なものです。

Ruby

1 def favorite 2 @feed_posts = current_applicant.favorite_posts 3 end

モデルは以下のように記述しています。

Ruby

1 2class Shop < ActiveRecord::Base 3 has_one :shop_basic, dependent: :destroy, foreign_key: 'id',autosave: true 4 has_one :post, dependent: :destroy, foreign_key: 'id',autosave: true 5end 6 7class Post < ActiveRecord::Base 8 belongs_to :shop, foreign_key: "id", autosave: true 9 has_many :favorites 10 has_many :favorite_users, through: :favorites, source: :user 11end 12 13class User < ActiveRecord::Base 14 has_many :favorites 15 has_many :favorite_posts, through: :favorites, source: :post 16end 17 18class Fav < ActiveRecord::Base 19 belongs_to :user 20 belongs_to :post 21end

Viewで、
<%= pt.post_title %>
はうまく取得できているようなのですが、なぜこの場合、Postと関係を持つShopの情報が取得できないのでしょうか。
FavoriteとShopにリレーションが直接無いためかと思い、それぞれにhas_manyやbelongs_toなどいろいろ試してはみたのですが、うまくいきません。

どうすればこのリレーションでshopのデータを取得できるでしょうか。
ご教示よろしくお願いいたします。


情報追加
ShopBasicのモデルになります。

Ruby

1class SalonBasic < ActiveRecord::Base 2 belongs_to :shop, autosave: true, foreign_key: 'id' 3 4 before_create do 5 self.id = shop.id 6 end 7 8end

Ruby

1# == Schema Information 2# 3# Table name: shops 4# 5# id :integer not null, primary key 6# email :string default(""), not null 7# encrypted_password :string default(""), not null 8# number_of_post :integer default(1), not null 9# reset_password_token :string 10# reset_password_sent_at :datetime 11# remember_created_at :datetime 12# sign_in_count :integer default(0), not null 13# current_sign_in_at :datetime 14# last_sign_in_at :datetime 15# current_sign_in_ip :inet 16# last_sign_in_ip :inet 17# created_at :datetime not null 18# updated_at :datetime not null 19# 20# Indexes 21# 22# index_salons_on_email (email) UNIQUE 23# index_salons_on_reset_password_token (reset_password_token) UNIQUE 24#

Ruby

1# == Schema Information 2# 3# Table name: shop_basics 4# 5# id :integer not null, primary key 6# shop_name :string default(""), not null 7# shop_hp_address :string 8# representive_name :string 9# contact_personnel_name :string 10# farm_name :string 11# postal_code :string 12# farm_prefectures :string 13# farm_address :string 14# use_email :string default(""), not null 15# phone_number :string 16# contact_personnel_phone :string 17# created_at :datetime not null 18# updated_at :datetime not null 19#

他のページのViewではshop_basicの値もうまく取得できているので、以下のfavoriteアクションが悪さをしているのかなと思ってはいるのですが…
favorite_postsとsalonがリレーションを持てていないみたいです。

Ruby

1 def favorite 2 @feed_posts = current_applicant.favorite_posts 3 end

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

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

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

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

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

hello-world

2015/07/31 12:25

shopからshop_basicへのリンクが辿れないようなので、 `ShopBasic`クラスと shops テーブルと shop_basics テーブルの構造も記述していただけると助かります
guest

回答1

0

ベストアンサー

通常、リレーションを持つモデルの場合、
リレーション先のIDを格納するカラムがあるはずなのですが、
一見したところそれがないのが原因のように思えます。

一般的なリレーションの場合以下の様なカラム構成になります。

Ruby

1# model定義 2class ShopBasic < ActiveRecord::Base 3 belongs_to :shop # class_name: Shop, foreign_key: :shop_id 4end 5 6class Shop < ActiveRecord::Base 7 has_one :shop_basic 8end 9 10# スキーマ 11create_table :shop_basic do |t| 12 t.integer :shop_id 13 # 以下略 14end

Railsの規約上、belongs_to関連にあるモデル側に、
belongs_toで対象としているクラスの名をアンダースコア化したものに_idを追加したカラムを持たせ、
そこに関連先のid属性の値を格納するのがデフォルトとなっています。
特にclass_name,foreign_keyオプションを指定しない場合、
上記ルールで実装されているものとして、フレームワーク側は判断します。

質問に書いてあるソースではSalonBasicとなっていますが、多分、ShopBasicだと解釈して
1.shop_basicにshopのid属性を格納するカラムがない
2.belongs_toで指定しているオプションがおかしい
(自id属性を格納するカラムにリレーション先のid属性を格納するように設定されている)
belongs_to :shop, autosave: true, foreign_key: 'id'
これだと、自分のテーブルのidカラムに参照先のidを格納しているという定義になってしまうので、正常なリレーションが作れないように思われます。

この辺を押さえて、再度ソースを見直してみてはどうでしょう?

投稿2015/08/01 00:12

rifuch

総合スコア1901

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

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

jusco

2015/08/01 00:59

互いにforeign_keyでIDを指定して関係を持たせてはいたのですが、そこがエラーの原因になっているかもしれないですね>< 見なおしてみます!ありがとうございましたm(__)m
rifuch

2015/08/01 01:20

railsのリレーションは、リレーション先のidがどこかに格納されていないと実現できないので、そこのあたりを理解するのが大事だと思います。 自テーブル参照なんかのちょっと面倒なリレーションを調べて見ると、foreign_keyと格納カラムの関係の理解が深まると思いますよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問