LoginSignup
0
0

More than 5 years have passed since last update.

Rails 5 : method = post といっているのに "No route matches [PATCH] "/engineer"" とか言われる不思議

Posted at

engineer/new.html.erb

<%= form_for @engineer, url: url_for(controller: 'engineer', action: 'create', mothod: "post") do |f| %>
   :
  <%= f.submit %>
<% end %>

とまで、しているのに、
「更新」ボタンを押しても、下のように [PATCH] "/engineer" エラー

image.png

ちなみに route.rbは

:
resource :engineer
:

で、全てを任せています。。

なんかおかしいなと思って、色々探していたら答えは下のページに
http://xengineer.hatenablog.com/entry/2014/10/20/rails%E3%81%AEform_for%E3%81%AFPOST/PATCH%E3%82%92%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%82%8B

https://www.railstutorial.org/book/updating_and_deleting_users

Since web browsers can’t natively send PATCH requests (as required by the REST conventions from Table 7.1), Rails fakes it with a POST request and a hidden input field.2

There’s another subtlety to address here: the code form_for(@user) in Listing 10.2 is exactly the same as the code in Listing 7.15—so how does Rails know to use a POST request for new users and a PATCH for editing users? The answer is that it is possible to tell whether a user is new or already exists in the database via Active Record’s new_record? boolean method:

確かにブラウザから表示されているフォームのソースを見ると下の感じで、hiddenでpatchが定義されている!

image.png

原因

engineer_controller.rb で定義していたこれが原因

    def new
        @engineer=Engineer.new
        @engineer.build_engineer_hiring
        @engineer.build_person_info
        @engineer.office = Office.first
        @engineer.engineer_registration_type_id = EngineerRegistrationType.select(:id).first
    end

ちなみに、engineer.rb がこれで、has_one :offcie, through: :engineer_hiringで定義している部分に値を入れるのが気にくわないらしい。

class Engineer < ApplicationRecord
    has_one :engineer_registration_type
    has_one :engineer_hiring, autosave: true
    has_one :office, through: :engineer_hiring
    belongs_to :person_info, autosave: true
end

以下ならOK

    def new
        @var.title=t("cmn_sentence.newTitle",model:Engineer.model_name.human)
        @engineer=Engineer.new
        @engineer.build_engineer_hiring
        @engineer.build_person_info
        @engineer.engineer_hiring.office = Office.first
        @engineer.engineer_registration_type_id = EngineerRegistrationType.select(:id).first
    end

さて。。 has_one through: の仕様について

確かに、元の書き方だと、

 @engineer.office = Office.first

と段階で、insert文が走ってしまう。この段階で何が起きているか深掘りするのはまた後でにするとして、(ER図を示さないと難しいと思うので・・)

@engineer.build_engineer_hiring(office: Office.first)

とすることで、エラーは出なくなった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0