lasciatemi iniziare dicendo che questo potrebbe anche essere un problema di modellazione e sono aperto a suggerimenti di modelli.Rails 4 Come modellare un modulo con una raccolta di checkboxes con altro campo di testo
Caso di utilizzo: Ho un modulo e devo consentire a un utente di selezionare una casella di controllo sulla categoria del suo post. Se non ci sono categorie che si adattano al loro post, l'altra categoria mostrerà un campo di testo per l'utente per aggiungere una categoria personalizzata. Questo dovrebbe farebbe per la creazione e l'aggiornamento di moduli annidati
DB Modeling
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.string :name, null: false
t.timestamps null: false
end
reversible do |dir|
dir.up {
Category.create(name: 'Hats')
Category.create(name: 'Shirts')
Category.create(name: 'Pants')
Category.create(name: 'Shoes')
Category.create(name: 'Other')
}
end
create_table :categorizations, id: false do |t|
t.belongs_to :post, index: true, null: false
t.belongs_to :category, index: true, null: false
t.string :value
end
end
end
App modelle
class Post < ActiveRecord::Base
has_many :categorizations
accepts_nested_attributes_for :categorizations, allow_destroy: true
has_many :categories, through: :categorizations
accepts_nested_attributes_for :categories
end
class Category < ActiveRecord::Base
has_many :posts
end
Controller:
def update
if @post.update(post_params)
flash.now[:success] = 'success'
else
flash.now[:alert] = @post.errors.full_messages.to_sentence
end
render :edit
end
private
def set_post
@post = Post.find(params[:id])
(Category.all - @post.categories).each do |category|
@post.categorizations.build(category: category)
end
@post.categorizations.to_a.sort_by! {|x| x.category.id }
end
def post_params
params.require(:post).permit(:name, :description,
categorizations_attributes: [ :category_id, :value, :_destroy],
)
end
Vista:
= f.fields_for :categorizations do |ff|
= ff.check_box :_destroy, { checked: ff.object.persisted? }, '0', '1'
= ff.label :_destroy, ff.object.category.name
= ff.hidden_field :category_id
= ff.text_field :value if ff.object.category.other?
Tuttavia con la soluzione di cui sopra continuo a correre per duplicare errori di registrazione durante il salvataggio. Non sono sicuro del perchè ciò stia succedendo? C'è un modo migliore per farlo?
Con questa soluzione dovrei tenere traccia del tipo di categoria nel modello, corretto? Inseriresti anche molte categorie che non mostrerei mai. – Matt
Non sono sicuro al 100% di cosa intenda dover tenere traccia del tipo di categoria. Se desideri che ciascuna delle categorie "Altro" sia trattata in modo diverso rispetto alle categorie "originali", puoi creare una sottoclasse (ereditarietà di una tabella singola). Ma sì, creerebbe molte categorie che non mostrereste. Non sono sicuro se questo è un vero problema però. –