Bonjour,
Pour les besoins d'une application, j'ai besoin de sortir du pattern habituel de RoR.
J'ai une liste de voitures (id, brand) avec système de CRUD classique.
# model
class Car < ActiveRecord::Base
validates :brand, presence: true
end
# controller
def index
@cars = Car.all
end
def new
@car = Car.new
end
/ view
= simple_form_for @car do |f|
= f.input brand
Plutôt qu'être dans un CRUD assez classique,
je souhaite avoir dès l'index un formulaire avec tous les véhicules dans des zones de texte (un peu à la méthode des nested fields)
Une solution que j'avais envisager, c'était de faire un modèle parent :
(exemple de code)
# model
class Vehicle < ActiveRecord::Base
has_many :cars
accepts_nested_attributes_for :cars
end
class Car < ActiveRecord::Base
validates :brand, presence: true
end
# controller
def index
@cars = Car.all
end
def new
@vehicle = Vehicle.includes(:cars).where(cars: { id: params[:id] }).first
end
/ view
= simple_form_for @vehicle do |f|
= f.simple_fields_for :cars do |c|
= c.input :brand
Dans un soucis de 'perfectionnisme', ça ne m'intéresse pas de créer spécialement une table, et je souhaite savoir s'il y a un moyen plus propre ?
J'ai regardé du côté de la gem Reform de Trailblazer pour créer des "objets virtuels" composé d'une collection de voiture, je galère un peu et du coup je souhaitais avoir l'avis de développeur plus expérimenté :)
(Au delà de ce soucis, je souhaite également créer des formulaires avec des objets qui n'ont parfois aucun rapport, mais avec "1 seul bouton Enregistrer")
La solution se cache dans la simplicité.
J'avais rapidement zappé les chapitres sur les helpers de Rails pour la création de formulaire et je suis allé quasi directement sur la gem Simple Form.
Cette gem est très bien pour des formulaires simples & classiques, mais dès que l'on veut faire des formulaires un peu plus élaboré, elle n'offre pas assez de souplesse.
Pour ceux que ça intéresse, une solution (améliorable) que j'ai trouvé, je met le code brute, il est je pense assez simple à compendre.
Routes
resources :cars
match '/cars', to: 'cars#update_all', via: [:patch, :put]
Contrôleur
def index
@cars = Car.all
end
def update_all
cars_params = params.require(:cars) # à améliorer pour ne prendre que les champs autorisés
# valeur de cars_params
# { "1" => { "brand" => "Renault" }, "2" => { "brand" => "Peugeot" }, "3" => { "brand" => "Citroen" } }
if Car.update(cars_params.keys, cars_params.values)
redirect_to cars_path, :notice => "Les voitures ont été mises à jour."
else
@cars = Car.all
render :index
end
end
Vue
= form_tag cars_path, { method: :put } do
- @cars.each do |car|
hr
= fields_for "cars[]", car do |c|
div
= c.label(:brand, "Marque")
= c.text_field(:brand)
div
= submit_tag("Mettre à jour")