最初の質問への回答
:user
1 つの解決策は、:course
読み取り専用としてマークすることです。
attr_readonly :user_id, :course_id
このようにして、作成時に設定できますが、更新時には設定できません。将来更新可能にしたい場合は、登録モデルに特別なメソッドを作成し、@registration.update_dangerous_stuff(params)
より高い権限を持つユーザーがアクセスできるコントローラー アクションでのみこのメソッドを使用できます。update_column
メソッドは、これらのフィールドを変更するために、 の行に沿って何かを使用します。
もう 1 つの方法は、ユーザーとコースを設定するための仮想属性を作成することです。これには、現在ユーザーまたはコースを設定できるかどうかを決定するロジックがあります。これが例です。
attr_accessor :safe_user, :safe_course
attr_accessible :safe_user, :safe_course
before_save :set_user, if: 'user.blank?'
before_save :set_course, if: 'course.blank?'
def set_user
self.user = safe_user
end
def set_course
self.course = safe_course
end
したがって、フォームでは and の代わりに and フィールドを使用しsafe_user
ます。この場合、実際に設定され、それらが空白の場合にのみ設定され、実際にアクセス可能として公開されることはありません。コールバック条件をいじることで、このルールをバイパス可能にすることができます。safe_course
user
course
user
course
2番目の質問への回答
複雑な形式で一連のデータを送信する場合、このデータのどれが意味を持ち、どれが単なるプレースホルダーであるかを判断する方法を考え出すのはあなた次第です。意味のあるデータが送信されない場合は、登録を作成しないでください。ネストされたフォームに触れたことがない場合とは対照的に、誰かが実際に入力しようとして間違いを犯したことを確認するには、どのフォームフィールドが「十分」であるかを判断する必要があります。それを判断する簡単な方法がない場合、その方法の 1 つは、ネストされたフォームに「この登録を追加」チェックボックスを追加することです。そのチェックボックスがチェックされている場合、作成が試行され、検証が実行されます。その後、javascript を追加してこのチェックボックスを非表示にし、ネストされたフォームのいずれかのフィールドをアクティブにした場合に自動的にチェックすることができます。
バックエンドでこの動作を容易にするために、accepts_nested_attributes_for
rails メソッドがあります。たとえば、コースモデルでは次のように言えます。
accepts_nested_attributes_for :registrations,
reject_if: -> attrs { attrs[:name].blank? }
# Don't forget this too
attr_accessible :registrations_attributes
Rails にはショートカットも用意されています。
accepts_nested_attributes_for :registrations, reject_if: :all_blank
チェックボックスの場合はreject_if: -> attrs { attrs[:my_check_box] == '1' }
、 などと言うことができます。
与えられたprocの条件が満たされない場合、登録を作成して検証するのではなく、登録を単に無視することをreject_if
Railsに伝えます。
これがあなたに遊び心のあるアイデアを与えてくれることを願っています。