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

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

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

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

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

1回答

1269閲覧

undefined method `build_address' for Order(Table doesn't exist):Class DBへデータの送信

tomato185

総合スコア29

Ruby

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

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2020/09/10 13:08

### 実現したいこと
ruby on rails 初心者です。
views/orders/index.htmlの注文確定ボタンを押下すると、ordersテーブルとaddressesテーブルに
データが保存される仕組みを作成しております。


ordersテーブル 対 addressesテーブル= 1 対 1
productsテーブル 対 ordersテーブル = 1 対 多

### エラー文

undefined method `build_address' for Order(Table doesn't exist):Class Extracted source (around line #8): 6 @product= Product.find_by(id: current_user.id) 7 8 @order = Order.build_address 9 10 end 11

###コード

(views/orders/index.html.erb) ※該当部分 <%= form_for(@order) do |f|%> <%= f.hidden_field :product_id, value: product.id %> <%= f.hidden_field :quantity, value: cart_item.quantity %> <%= f.fields_for :addresses do |a|%> <%= a.hidden_field :user_id, value: current_user.id %> <%= a.hidden_field :last_name, value: session[:last_name] %> <%= a.hidden_field :first_name, value: session[:first_name] %> <%= a.hidden_field :furi_last_name, value: session[:furi_last_name] %> <%= a.hidden_field :furi_first_name, value: session[:furi_first_name] %> <%= a.hidden_field :postal_code, value: session[:postal_code] %> <%= a.hidden_field :prefecture, value: session[:prefecture] %> <%= a.hidden_field :address, value: session[:address] %> <%= a.hidden_field :store, value: session[:store] %> <%= a.hidden_field :how_to_pay, value: session[:how_to_pay] %> <% end %> <p><%= f.submit "注文確定", class: 'btn' %></p> <% end %>
(controllers/orders_controlles.rb) class OrdersController < ApplicationController def index cart = Cart.find_by(user_id: current_user.id) @cart_items = CartItem.where(cart_id: cart.id) @product= Product.find_by(id: current_user.id) @order = Order.build_address end def create @order = Order.new(order_params) if @order flash[:success] = "購入が完了しました。" redirect_to root_path else render "index" end end private def order_params params.require(:order).permit(:product_id, :quantity, address_attributes: [ :user_id, :last_name, :first_name, :furi_last_name, :furi_first_name, :postal_code, :prefecture, :address, :store, :how_to_pay ]) end end
(models/product.rb)※一部記載 class Product < ApplicationRecord has_many :cart_items has_many :orders end
(models/order.rb) class Order < ApplicationRecord belongs_to :product has_one :address accepts_nested_attributes_for :address end
(models/address.rb) class Address < ApplicationRecord belongs_to :order, inverse_of: :addresses end

###試した点
アソシエーションを確認

###補足情報(FW/ツールのバージョンなど)
ruby 2.6.6
rails '~> 5.2.4', '>= 5.2.4.3'

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

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

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

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

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

guest

回答1

0

ベストアンサー

@order = Order.build_addressではなくnewしてからかと思います。

def index @order = Order.new @order.build_address end

こちらに変更してみてください

投稿2020/09/10 13:29

necocoa

総合スコア209

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

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

tomato185

2020/09/10 13:44

necocoa様 ご回答ありがとうございます。 修正後、同じ箇所で、以下のエラーが出てしまいました。。。 unknown attribute 'order_id' for Address. ただ、この場合、addressesテーブルにはorder_idは必要ないのではないかと思うのですが、、、
tomato185

2020/09/10 13:51

ordersテーブルにはaddress_idカラムがあります。
necocoa

2020/09/10 14:00

Orderに has_one :address を付けてると思うんのですが、 その関連はどう探すと思いますか? たとえば product = Product.first が合った時、 product.orders をすると、Order.where(product_id = product.id)で捜します。 同じように order = Order.first order.address をするとAddress.where(order_id = order.id).limit(1)で捜します。 つまり、hasと言ってる時点でそのクラスが保有しているみたいな形になります。 よって、関連付けるために、関連先には親クラスのidが必要になります。
necocoa

2020/09/10 14:12

> ordersテーブルにはaddress_idカラムがあります。 こちらすれ違いでコメントしてしまいました。 1:1の場合は、どちら側がidを持っていても動きます。 そういう時はどちらがその情報を保有するのか、を考えるといいですね 今回の場合、注文が送り先を保有します。 (逆にしてみると、送り先が注文を保有する、になります) となると、Orderにhas_oneは合っていて、それを関連付けるためには Addressにorder_idのカラムを作る必要があります。 そして、Orderにはaddress_idは必要ないですね もしaddress_idがある場合、先にaddressを作って、orderにそのaddress_idを渡すことになりますが 注文を作るのが先ですよね?って思うとorderにaddress_idがあるのがおかしいことがわかります。
tomato185

2020/09/11 01:01

neccoca様 ご回答ありがとうございます。 大変勉強になりました! 先にOrderができるので、その時にAddress_idを持っていたらおかしいですね、、、 このあたりの知識が不足していたので、今後はそこも意識しながらDBを構築していきます! エラーはでなくなりましたが、よくよく考えると、購入予定の商品が2つ以上の場合を考えると、 先にorderを作るのはよくないかなと思い、先にaddressを作ることにしました。 なので、addresses : orders = 1対多 にしました。 それに伴って、いろんなところで変更をしたのですが、belongs_to: addressのところでエラーを はかれてしまいました。 みていただいてもよろしいでしょうか。
necocoa

2020/09/11 01:06

今回やりたかった部分は解決したので、別の質問をたてるのが良いかと思います!
tomato185

2020/09/11 01:08

necocoa様 ありがとうございます! 今から別の質問をたてるので、もしよければまたご回答よろしくお願い致します!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問