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

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

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

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

Ruby on Rails 4

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

Q&A

解決済

2回答

2414閲覧

【Ruby on Rails】accepts_nested_attributes_forで親の任意のデータを子にセットしたい

pecchan

総合スコア555

Ruby on Rails

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

Ruby on Rails 4

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

0グッド

0クリップ

投稿2017/03/14 01:22

編集2017/03/14 07:37

社員の新規登録時に、同じ画面で
資格も複数行登録したいです。

親:社員
子:資格

色々と参考にしながら、accepts_nested_attributes_forを使い
親子関係のモデルを同時に登録するところまで出来ました。

子モデル側のフィールドに、親モデル名_idを持つことで
自動で親のキーをセットしてくれますが、
この他にも親のデータをセットしたい場合、どこに何を記述するのが定石でしょうか?

例えば、受注伝票なら
受注伝票キーは自動でセットされますが
受注伝票番号も同じタイミングでセットしたい場合です。

今回の場合ですと、
viewで入力された社員名(emp_name)を
子のemp_nameにもセットして登録したいです。

宜しくお願い致します。

社員モデル

ruby

1class Employee < ApplicationRecord 2 3 has_many :license, dependent: :delete_all 4 5 accepts_nested_attributes_for :license, allow_destroy: true 6 7 validates :emp_name, presence: true 8end 9

社員コントローラ

ruby

1class EmployeesController < ApplicationController 2 before_action :set_employee, only: [:show, :edit, :update, :destroy] 3 4 # POST /employees 5 # POST /employees.json 6 def create 7 @employee = Employee.new(employee_params) 8 9 10 respond_to do |format| 11 if @employee.save 12 format.html { redirect_to @employee, notice: 'Employee was successfully created.' } 13 format.json { render :show, status: :created, location: @employee } 14 else 15 format.html { render :new } 16 format.json { render json: @employee.errors, status: :unprocessable_entity } 17 end 18 end 19 end 20 21 22 private 23 # Use callbacks to share common setup or constraints between actions. 24 def set_employee 25 @employee = Employee.find(params[:id]) 26 end 27 28 # Never trust parameters from the scary internet, only allow the white list through. 29 def employee_params 30 params.require(:employee).permit( 31 :emp_code, 32 :emp_name, 33 :retire_date, 34 lisence_attributes:[:id, :emp_code, :emp_name, :_destroy]) 35 end 36end 37

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

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

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

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

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

guest

回答2

0

ベストアンサー

保守性の観点から行くとnested_attribute_forを使うより
active_modelを使ってきっちり描くのが業務ソフトウェア的には正解です。
ただ、nested_attribute_forのお手軽さには抗えないものがあります。
前にアドバイスした通り

ruby

1class License < ApplicationRecord 2before_save :set_parent_dep_name 3def set_dep_name 4self.dep_name||=self.try(:employee).try(:dep_name) 5end 6end

というふうにやりたいのですが、Licenseがsaveされる時点で、updateなら上記コードで問題なく動くのですが
createだと、Employeeがsaveされていませんので、子から親にアクセスすることはできません。
というわけで方法は3つ
0. active_modelを使ってmodelの関連性保存の順番等を綺麗に書く

  1. 先にemployeeを一回セーブして(find_or_create_by等)無理やりUpdateに持ち込む(コード一行で済む)
  2. controller層でparamを書き換える。

おすすめ順は2→1→3ですかね。
controller層に書くと後が大変ですしactive_modelを理解しきるのは
結構大変なので。
とりあえず、1が絶対的な正解ですが、お手軽さでnested_attribute_forを選んだなら、
少しレールから、ずれてもいいよねってことで。

まあ、アドバイスになれば幸いです。

投稿2017/03/14 09:15

moke

総合スコア2241

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

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

pecchan

2017/03/14 22:40

仰る通り、業務ソフトウェア的に正しい方法が知りたかったところです。 大変参考になりました。有難う御座います。 ということは、トランザクションで囲ってやる必要がありそうですね。 頑張ってみます。 本当に有難う御座いました!
guest

0

受注伝票番号をアップデートするタイミング(おそらくコントローラのUpdate)で伝票番号も子モデルの入れたいカラムにセットしてSaveすればはいりますよ。
IDは自動セットとのことですが、保守性を考えるとこちらも一応同じようにSaveしたほうがいいかと。

投稿2017/03/14 02:26

tqkqt0

総合スコア155

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

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

pecchan

2017/03/14 02:39

恐れ入ります。 「受注伝票番号」をアップデートする必要はありません。 受注伝票の新規作成時に、伝票番号をセットしたいです。 なので、コントローラではCreateかもしれません。 保守性の観点から、IDの自動セットよりSaveで。とのこと納得です。 ですが、accepts_nested_attributes_forを使うにあたり、 子モデル側のフィールドに、親モデル名_idを持つ→自動で親キーがセットされる は、こういう手順なのかなと思っておりました。 Ruby on Rails初心者です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問