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

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

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

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

Q&A

解決済

1回答

224閲覧

rails アソシエーションで動作がうまくいかなくなる際の対処法

takeke

総合スコア60

Ruby

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

0グッド

1クリップ

投稿2018/04/29 11:26

ecサイトのオーダー関連の質問させていただいた者です。
https://teratail.com/questions/124047

今色々やっているのですがいまだにいい結果が出ていませんが、そこで新たに質問が出来たのでさせて頂きます。

先ほどの質問では注文の際の情報を新たなテーブルを作って、後から何が注文されたかなど見れるようにと思ったのですが、色々やっていくうちに、新たなテーブルを作らなくてもデータを引き出せるようになりました。そこで問題が起きるのですが、アソシエーションでカートの中の商品(line_items)とオーダー(orders)を関連づけているのですが、これがうまく動作しません。

今までは関連付けしないで作っていたのですが、これを関連づけしたところ、rails c コマンド内にて必要なデータの全て得ることができました。しかしrails sでアプリを動かそうとするとカート機能動かなくなってしまいます。

ブラウザ上では何も起こらず、クロームの検証でみるとサーバーエラーが起きています。ターミナル上ではテンプレートエラーが出ていて該当箇所と思われる部分を修正方法がわからないのでとりあえず消してみたのですがうまくいきませんでした。

以下エラー内容やコード載せます。

クロームの検証

POST http://localhost:3000/line_items?product_id=27 500 (Internal Server Error) Rails.ajax @ rails-ujs.self-817d9a8cb641f7125060cb18fefada3f35339170767c4e003105f92d4c204e39.js?body=1:189 Rails.handleRemote @ rails-ujs.self-817d9a8cb641f7125060cb18fefada3f35339170767c4e003105f92d4c204e39.js?body=1:546 (anonymous) @ rails-ujs.self-817d9a8cb641f7125060cb18fefada3f35339170767c4e003105f92d4c204e39.js?body=1:146

ターミナル

ActionView::Template::Error (No route matches {:action=>"decrease", :controller=>"line_items", :id=>#<LineItem id: nil, product_id: 27, cart_id: 175, created_at: nil, updated_at: nil, quantity: 1, order_id: nil>}, possible unmatched constraints: [:id]): 7: <dd class="item_price test1"><%= number_to_currency( line_item.product.price, :locale => 'jp') %></dd> 8: <dd class="test1 test2">&times; <%= line_item.quantity %> 個 =</dd> 9: <dd class="test1 test2 price_item"> <%= number_to_currency( line_item.total_price, :locale => 'jp') %></dd> 10: <dd class="test1 test2 test3"><%= button_to '-', decrease_line_item_path(line_item), :method => :put, remote: true %></dd> 11: <dd class="test1 test2 test3"><%= button_to '+', increase_line_item_path(line_item), :method => :put, remote: true %></dd><br><hr> 12: <!-- <td><%#= button_to '削除', line_item, :method => :delete %></td> --> 13: </dl> app/views/line_items/_line_item.html.erb:10:in `_app_views_line_items__line_item_html_erb___6180940__636402918' app/views/carts/_cart.html.erb:4:in `_app_views_carts__cart_html_erb__325764855__636433798' app/views/layouts/application.html.erb:136:in `_app_views_layouts_application_html_erb__754154700_109666420' app/controllers/line_items_controller.rb:43:in `block (2 levels) in create' app/controllers/line_items_controller.rb:36:in `create'

指摘されていると思われる:action=>"decrease"と、アクションincrease使っている箇所のviewを削除した後のターミナル

Started POST "/line_items?product_id=28" for 10.0.2.2 at 2018-04-29 11:15:06 +0000 Processing by LineItemsController#create as JS Parameters: {"product_id"=>"28"} Cart Load (2.1ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT ? [["id", 175], ["LIMIT", 1]] Product Load (1.6ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 28], ["LIMIT", 1]] LineItem Load (2.5ms) SELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = ? AND "line_items"."product_id" = ? LIMIT ? [["cart_id", 175], ["product_id", 28], ["LIMIT", 1]] (0.1ms) begin transaction Product Load (1.4ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 28], ["LIMIT", 1]] (0.1ms) rollback transaction Rendering line_items/new.html.erb within layouts/application Rendered line_items/_form.html.erb (1.3ms) Rendered line_items/new.html.erb within layouts/application (24.9ms) LineItem Load (2.0ms) SELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = ? [["cart_id", 175]] Product Load (1.8ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 25], ["LIMIT", 1]] Rendered collection of line_items/_line_item.html.erb [2 times] (5.2ms) Rendered carts/_cart.html.erb (31.0ms) Completed 200 OK in 1235ms (Views: 1210.1ms | ActiveRecord: 11.6ms)

line_items_controller.rb

class LineItemsController < ApplicationController skip_before_action :authorize, only: :create before_action :set_line_item, only: [:show, :edit, :update, :destroy] def index @line_items = LineItem.all end def show @line_item = LineItem.find(params[:id]) respond_to do |format| format.html # show.html.erb format.json { render json: @line_item } end end def new @line_item = LineItem.new respond_to do |format| format.html # new.html.erb format.json { render json: @line_item } end end def edit @line_item = LineItem.find(params[:id]) end def create @cart = current_cart product = Product.find(params[:product_id]) @line_item = @cart.add_product(product.id) respond_to do |format| if @line_item.save # format.html { redirect_to store_url, notice: 'Line item was successfully created.' } format.html { redirect_to store_url} format.js { @current_item = @line_item} format.json { render json: @line_item, status: :created, location: @line_item } else format.html { render action: "new" } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end end def update @line_item = LineItem.find(params[:id]) respond_to do |format| if @line_item.update(line_item_params) format.html { redirect_to @line_item, notice: 'Line item was successfully updated.' } format.json { render :show, status: :ok, location: @line_item } else format.html { render :edit } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end end def destroy @line_item = LineItem.find(params[:id]) @line_item.destroy respond_to do |format| format.html { redirect_to store_url, notice: 'Line item was successfully destroyed.' } format.json { head :no_content } end end def decrease @cart = current_cart @line_item = @cart.decrease(params[:id]) respond_to do |format| if @line_item.save format.html{redirect_to store_url} format.json{head :ok} else format.html{render action: "edit"} format.json{render json: @line_item.errors, status: :unprocessable_entity} end end end def increase @cart = current_cart @line_item = @cart.increase(params[:id]) respond_to do |format| if @line_item.save format.html{redirect_to store_url} format.json{head :ok} else format.html{render action: "edit"} format.json{render json: @line_item.errors, status: :unprocessable_entity} end end end private def set_line_item @line_item = LineItem.find(params[:id]) end def line_item_params params.fetch(:line_item, {}) end end

line_item.rb

class LineItem < ApplicationRecord belongs_to :order #←これをなくすと動作はうまくいきます。ただしデータが引き出せなくなります belongs_to :product belongs_to :cart def total_price product.price * quantity end end

order.rb

class Order < ApplicationRecord PAYMENT_TYPES = ["現金","クレジットカード","注文書"] has_many :line_items, dependent: :destroy has_many :order_items, dependent: :destroy belongs_to :user validates :name, :address, :email,:user_id, presence: true validates :pay_type, inclusion: PAYMENT_TYPES default_scope -> { order(created_at: :desc) } def add_line_items_from_cart(cart) cart.line_items.each do |item| item.cart_id = nil line_items << item end end end

該当箇所は以上なのですが、何かお気付きの箇所などありましたらご助言いただけると助かります。他のデータも必要でしたら載せますのでおっしゃってください。
よろしくお願いいたしますm(._.)m

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

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

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

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

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

guest

回答1

0

自己解決

自己解決できました。
今回の問題は、line_itemとorder間のvalidationの問題でした。

アソシエーションを組んでいて、カートに商品を入れる際に(line_item)をcreateすることになるのですが(line_item)はbelongs_to :orderなのでorderがないと存在できなかったのです。なのでここでエラーでした。結論としてこのエラーを回避、orderがなくてもcreateできるようにすればOKでした!なのでcreateの記述でsaveをsave(validate: false)だけで通るようになりました。

かなり迷ったので重ねて質問してしまいましたのでそちらも載せて起きます
https://teratail.com/questions/124188

ありがとうござしましたm(._.)m

投稿2018/04/30 12:01

takeke

総合スコア60

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問