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

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

ただいまの
回答率

91.06%

  • Ruby on Rails

    6021questions

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

  • Ruby on Rails 4

    2268questions

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

railsで複数のコントローラから1つのテーブル(モデル)にデータを保存したい

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 110

tshr

score 10

現在ECサイトを作成しています。
フラグをたてて管理したいのですが1つのcontrollerでdestroyアクションを実行してしまうと会社の住所登録と配送先の住所登録の両方が消えてしまいます。
そこでcontrollerを2つ作成し、それぞれの内容を1つのモデルに保存しようと考えましたが、うまくいきません。

実現したいこと

  • 住所モデル(adress)は1つ
  • 会社の住所登録、編集用のcontroller(c_adresses_controller)
  • 配送先の住所登録、編集用のcontroller(s_adresses_controller)

として2つのcontrollerの内容を1つの住所モデルに保存したいのですがルーティングエラーが発生します。
原因がわかる方、解決方法がわかる方がいらっしゃいましたらよろしくお願いします。

動作環境

OS:mac
Ruby:2.3.5
Ruby on Rails: 4.2.5

エラー内容

イメージ説明
イメージ説明

現状

  • deviseを利用している
  • Adress(住所)モデルを1つ作成している
  • controllerは2つ作成している(c_adress(会社住所) と s_adress(配送先住所))
  • form_forを利用している
  • 会社住所、配送先住所をフラグを使って判断する
  • 2つの controller と View の内容はほぼ同じ
  • 下記のコードの controller と View は会社住所(s_adress)関連のものです

試したこと

下記のサイトを参考にしてみましたが同じエラーが発生しました

railsでコントローラに関連付けられているテーブルとは別のテーブルのデータを読み書きするにはどうすればいいんでしょうか?

該当のソースコード(抜粋、devise関連は省略してあります)

config/routes.rb

Rails.application.routes.draw do

  #住所関連
  resources :adresses, :only => [:index]
  resources :c_adresses, :except => [:index, :show]
  resources :s_adresses, :except => [:index, :show]

  root to: 'tops#index'
end


schema.rb

ActiveRecord::Schema.define(version: 20180106142022) do

  create_table "adresses", force: :cascade do |t|
    t.integer  "user_id",       limit: 4
    t.string   "postal_code",   limit: 255
    t.string   "city",          limit: 255
    t.integer  "c_adress_flg",  limit: 4
    t.integer  "s_adress_flg",  limit: 4
    t.datetime "created_at",                null: false
    t.datetime "updated_at",                null: false
  end

end


app/controllers/s_adresses_controller.rb

class SAdressesController < ApplicationController
 #↓↓ここを参考サイトをもとに追記しましたがエラー内容は変わりませんでした。
  model :adress

  def new
    @adress = Adress.new
    @submit = "登録する"
  end

  def create
    @adress = Adress.new(adress_params)

    if @adress.save
      # redirect_to adresses_url(id: current_user.id)
      redirect_to adresses_path
    else
      render 'new'
    end
  end

  private
  def adress_params
    params.require(:adress).permit(:user_id, :postal_code, :city, :street, :others, :c_adress_flg, :s_adress_flg)
  end

end

app/views/s_adresses/new.html.erb

<%= form_for(@adress) do |f|%>

<!-- 郵便番号 -->
    <div class="field">
      <%= f.label :postal_code, '郵便番号' %>
      <%= f.text_field :postal_code, autofocus: true %>
    </div>
<!--市区町村-->
    <div class="field">
      <%= f.label :city, '市区町村'%>
      <%= f.text_field :city, autofocus: true %>
    </div>

    <!-- 通常配送先の可否 -->
      <div class="field">
        <%= f.check_box :s_adress_flg,{}, 2, 1 %><%= f.label :s_adress_flg, '通常配送先にする'%>
      </div>

      <%= f.hidden_field :user_id, value: current_user.id %>
      <%= f.hidden_field :c_adress_flg, :value => 0 %>

  <div class="actions">
    <%= f.submit @submit %>
  </div>
<% end %>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+1

こんにちは。

まず前提の確認として、routes.rb に

resources :adresses, :only => [:index]


とあるので、adressコントローラ(class AdressesController < ApplicationController)
も作るものと思えました。
その上で、エラーメッセージには

No route matches [POST] "/adresses"

とあり、このエラーが出ないようにしたいということは、住所の新規作成は、
POST /adresses によって、会社住所と配送先住所のどちらも
作成できるようにしたいという趣旨だと思えますが、それでよいでしょうか?

もし、それであれば、routes.rb で

resources :adresses, :only => [:index]


としているところを、:createも追加して

resources :adresses, :only => [:index, :create]


とすればよいと思います。

こうすれば、POST /adresses が、adresses#create にルーティングされます。

ただ、この場合は、
POST /c_adresses

POST /s_adresses
は不要かもしれません。

もし、会社住所の新規作成は、POST /c_adresses で行い、
配送先住所の新規作成は、POST /s_adresses で行う
ということであれば、POST /adresses は用意する必要は
ないので、

No route matches [POST] "/adresses"

というエラーになっても妥当といえます。

以上参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 91.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby on Rails

    6021questions

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

  • Ruby on Rails 4

    2268questions

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