I have 3 model here : NewWord
, VerbForm
and AdjForm
.
In NewWord
model , I have a column word_type
stored type of word: Adj Noun Verb Phrase GenericWord
Each NewWord may have 1 VerbForm or 1 AdjForm
Class NewWord < ApplicationRecord
has_one :adj_form, dependent: :destroy
has_one :verb_form, dependent: :destroy
accepts_nested_attributes_for :adj_form, allow_destroy: true
accepts_nested_attributes_for :verb_form, allow_destroy: true
def self.types
%w(Adj Noun Verb Phrase GenericWord)
end
end
class NewWord::AdjForm < ApplicationRecord
belongs_to :new_word
end
class NewWord::VerbForm < ApplicationRecord
belongs_to :new_word
end
I use this form to create a word alongside with it forms
<%= simple_form_for new_word, remote: true do |f| %>
<div class="error_section"></div>
<%= f.input :word %>
<%= f.input :kanji_version %>
<%= f.input :word_type, collection: NewWord.types %>
<%= f.simple_fields_for :verb_form do |v| %>
<%= v.input :verb_type %>
<%= v.input :dictionary_form %>
# Other fields
<% end %>
<%= f.simple_fields_for :adj_form do |a| %>
<%= a.input :adj_type %>
# Other fields
<% end %>
<%= f.button :submit %>
<% end %>
My idea here is when user select word_type
from dropdown, I can use Javasript to hide or show fields for AdjForm
or VerbForm
, or both. Then at submit, I only save AdjForm
if new word's word_type
is 'Adj', or VerbForm
if word_type
is 'Verb'.
So, how can I achieve this ? Since nested object saved automatically when I run this in new word create
method: @new_word.save.
?
I have try reject_if
but it only returns params for nested object only!
accepts_nested_attributes_for :adj_form, allow_destroy: true, reject_if: :not_adj
def not_adj(att)
att['new_word']['word_type'] != 'Adj' # Found out "att" here only has attributes of AdjForm , not NewWord !
end
In the controller, before saving, check the word_type value and discard the params that you dont want to save.
new_words_controller.rb
def create
prepare_params
@new_word = NewWord.new(new_word_params)
if @new_word.save
# ...
else
# ...
end
end
private
def prepare_params
params.delete[:verb_form] if params[:word_type] == "Adj"
params.delete[:adj_form] if params[:word_type] == "Verb"
params
end
This assumes you have whitelisted the parameters for new_word and its associations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.