engineer/new.html.erb
<%= form_for @engineer, url: url_for(controller: 'engineer', action: 'create', mothod: "post") do |f| %>
:
<%= f.submit %>
<% end %>
とまで、しているのに、
「更新」ボタンを押しても、下のように [PATCH] "/engineer" エラー
ちなみに 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が定義されている!
原因
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)
とすることで、エラーは出なくなった。