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

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

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

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

Q&A

解決済

1回答

1060閲覧

Railsでアカウントの内容を更新しようとするとRouting Errorが発生してしまい解決方法がわからないのでご教示お願いします。

koume

総合スコア458

Ruby on Rails 5

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

0グッド

0クリップ

投稿2018/08/08 13:17

編集2018/08/09 00:46

Rails5.1.3でWebアプリケーション制作の勉強をしています。
アカウント内容を変更しようとして「更新」ボタンをクリックするとRouting Errorが出てしまいます。

エラー内容 Routing Error No route matches [POST] "/admin/histories/1"

関係コードは以下になります。

routes.rb resources :histories do get :purchase end
edit.html.erb <% @title = '発送チェック' %> <h1><%= @title %></h1> <div id="generic-form"> <%= form_for @history_form, as: 'form', url:[ :admin, @history_form.history ] do |f| %> <%= render 'form', f: f %> <div class="buttons"> <%= f.submit'更新' %> <%= link_to 'キャンセル', :admin_root %> </div> <% end %> </div>
_history_fields.html.erb <%= f.fields_for :history, f.object.history do |ff| %> <%= markup do |m| p = HistoryFormPresenter.new(ff, self) p.with_options(required: true) do |q| m << q.drop_down_list_block(:undispatched, '発送状況', History::UNDISPATCHED) end end %> <% end %>
_form.html.erb <%= FormPresenter.new(f, self).notes %> <fieldset id="history-fields"> <legend>発送状況</legend> <%= render 'history_fields', f: f, confirming: false %> </fieldset>
form_presenter.rb class FormPresenter include HtmlBuilder attr_reader :form_builder, :view_context delegate :label, :text_field, :password_field, :check_box, :radio_button, :text_area, :object, to: :form_builder def initialize(form_builder, view_context) @form_builder = form_builder @view_context = view_context end def notes markup(:div, class: 'notes') do |m| m.span '*', class: 'mark' m.text '印の付いた項目は入力必須です。' end end def text_field_block(name, label_text, options = {}) markup(:div, class: 'input-block') do |m| m << decorated_label(name, label_text, options) m << text_field(name, options) m << error_messages_for(name) end end def password_field_block(name, label_text, options = {}) markup(:div, class: 'input-block') do |m| m << decorated_label(name, label_text, options) m << password_field(name, options) m << error_messages_for(name) end end def date_field_block(name, label_text, options = {}) markup(:div, class: 'input-block') do |m| m << decorated_label(name, label_text, options) if options[:class].kind_of?(String) classes = options[:class].strip.split + [ 'datepicker' ] options[:class] = classes.uniq.join(' ') else options[:class] = 'datepicker' end m << text_field(name, options) m << error_messages_for(name) end end def drop_down_list_block(name, label_text, choices, options = {}) markup(:div, class: 'input-block') do |m| m << decorated_label(name, label_text, options) m << form_builder.select(name, choices, { include_block: true }, options) m << error_messages_for(name) end end def error_messages_for(name) markup do |m| object.errors.full_messages_for(name).each do |message| m.div(class: 'error-message') do |m| m.text message end end end end def decorated_label(name,label_text, options = {}) label(name, label_text, class: options[:required] ? 'required' : nil) end end
history_form_presenter.rb class HistoryFormPresenter < UserFormPresenter def order_field_block(name, label_text, options = {}) narkup(:div, class: 'input-block') do |m| m << text_field(name, options) m.span '(注文重量を選択してください。)', class: 'notes' m << error_messages_for(name) end end def purchase_date_field_block(name, label_text, options = {}) narkup(:div, class: 'input-block') do |m| m << text_field(name, options) m << error_messages_for(name) end end end
histories_controller.rb class Admin::HistoriesController < Admin::Base def show @customer = Customer.find_by(id: params[:id]) @history = History.where(customer_id: params[:id]) end def edit @history_form = Admin::HistoryForm.new(History.find_by(customer_id: params[:id])) end def update @history_form = Admin::HistoryForm.new(History.find_by(customer_id: params[:id])) @history_form.assign_attributes(params[:form]) if @history_form.save flash.notice = '発送完了しました。' redirect_to :admin_history_undispatched else flash.now.alert = '入力に誤りがあります。' render action: 'edit' end end

「更新」ボタンをクリックするとエラーが発生してしまうのですが、更新なのでcreateの[POST]ではなくupdateの[PATCH]だと思うのですが、なぜ[POST] "/admin/histories/1"にマッチするルートが存在しないとなるのかわかりません。

どなたか教えていただけないでしょうか?宜しくお願いします。

追記

history_form.rb class Admin::HistoryForm include ActiveModel::Model attr_accessor :history delegate :presisted?, :save, to: :history def initialize(history = nil) @history = history @history ||= History.new end def assign_attributes(params = {}) @params = params history.assign_attributes(history_params) end private def history_params @params.require(:history).permit(:order, :undispatched) end end

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

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

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

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

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

guest

回答1

0

ベストアンサー

なぜPATCHではないのか、というのは、form_forに渡しているのが@history_formだから、ではないでしょうか。
form_forのmethodは渡されたobjectが保存されているかどうか(object.respond_to?(:persisted?) && object.persisted?)でチェックしているのでした。

(たぶんhttps://github.com/rails/rails/blob/3576782888c307e3e192c44e332b957cd1174128/actionview/lib/action_view/helpers/form_helper.rb#L464ですよね)

そのため、

html

1 <%= form_for @history_form, as: 'form', url:[ :admin, @history_form.history ], method: "patch" do |f| %>

と陽にmethodを渡すか、あるいはAdmin::HistoryFormを何とかしてpersisted?を使えるようにするといいんではないでしょうか。

投稿2018/08/08 17:53

編集2018/08/08 17:54
takahashim

総合スコア1877

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

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

koume

2018/08/09 00:50

回答ありがとうございます。教えていただいたようにhistory_form.rbにpresisted?を追記しましたが 状況は同じで[POST]になってしまいます。[PATCH]にするにはどうしたらいいのでしょうか?教えていただけないでしょうか?
koume

2018/08/19 08:32

スペルミスでした。presisted?ではなくpersisted?でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問