Rails simple_form - validation errors for nested associations - ruby-on-rails

I'm having trouble displaying validation errors on my simple_form:-
= simple_form_for(#garage, url: garage_staff_path(#garage)) do |f|
.form-contents
= f.input :staff_ids, label: "Staff", required: true,
collection: #selectable_staff, input_html: { multiple: true, placeholder: "Staff" }
= f.simple_fields_for :garage_staff do |garage_staff|
= garage_staff.input :starts_at, as: :date_picker
I am creating GarageStaff entries which is a join model between Garage and Staff, so basically adding existing Staff to a Garage.
We have a collection select input, which allows selection of multiple staff
We have a date field, which in our API, will be applied to ALL selected staff
What I am trying to do is add a bootstrap validation error message for when the date submitted is blank, but I can't figure out how. The validation presently does work as I've added it to the model, it's just the error on the input field I can't get to work.
We have bootstrap validation error messages which will display if the form object is missing any attributes, but this is for an attribute on the object's association. To add to that, it's for bulk applying a date to many staff, not just one, or many.
Does anyone have any pointers for how I can get this to work?

Related

Rails Active Admin base errors - add direct anchor link to the field with error

I have a very long form inside Rails Active Admin.
I would like to customize the base errors messages, that is to say the errors displayed on top of the page (not the ones on each field), so that instead of just being the default one (see example below), the user could have inside this text a "shortlink", that is to say a link to the field with the error so that he can just click and be transported on the page to the field with the error.
Current error message:
Error message i would like to have
For example the text in the image above could become:
Images at least one image is required. Please check it.
Note that in my Camping form page, I can edit Camping attributes but also the Rooms (they have a belongs to/has_many relation with Camping model=> one camping has many Rooms)
So this should be appliable to both attributes of Camping but also to the attributes of the associated rooms if they turn out to have errors on the form submission
ActiveAdmin.register Camping do
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs "Information for the Camping" do
f.input :name,
f.input :city
end
f.inputs "Rooms" do
f.has_many :rooms,
allow_destroy: true,
heading: false,
new_record: true,
sortable_start: 0 do |room|
room.input :name,
room.input :room_nb,
room.input :facilities
end
end
end
I even am not sure if it should be done on config of Active Admin or more inside config of Formtastic, which is the form DSL Active Admin is using. Maybe the customization found in this post (Make semantic_errors render the exact error-message) could be used but it's way beyond my level:)

Validating a Rails form field that has to run through another model before saving

I have a Ruby on Rails (Ruby 2.5.1, Rails 5.1) application which deals with flights; among other things, it has a Flight model and an Airline model, with Flight belongs_to :airline and Airline has_many :flights. Airline has an iata_code column which contains the two-letter IATA airline code (i.e. AA, UA, WN, F9).
For the flight entry form, I want the user to be able to enter an arbitrary IATA code, rather than selecting an airline from a dropdown. If the IATA code the user enters matches a record in the Airline table, then the Flight.airline_id column should be set to that airline's ID. If the IATA code doesn't match an airline in my database, then the airline should be created using the IATA code provided, and that new airline's ID should be assigned to Flight.airline_id.
I currently have this working by having an Airline IATA code field in my add/edit flight form (note that the form field is named :airline_iata instead of :airline_id):
<%= f.label :airline_iata, "Airline code" %>
<%= f.text_field :airline_iata, class: "form-control code airline-iata", maxlength: 2, placeholder: 'AA' %>
Then, in my Flights controller's create and update action, I try to look up the airline before I save the flight, and set the airline_id parameter (create is below, but update is similar):
def create
params[:flight][:airline_id] = Airline.find_or_create_by!(:iata_code => params[:flight][:airline_iata].upcase).id
#flight = current_traveler.flights.build(flight_params)
if #flight.save
redirect_to event_path(current_traveler.event)
else
render "new"
end
end
This approach is working for me, except that I am unable to figure out how to do validation on the Airline IATA code field from the flight form. The Airline model validates the code (presence: true, length: { is: 2 }, uniqueness: { case_sensitive: false }), so if the user inputs an invalid IATA code, the Airline creation will fail, and thus the Flight creation will fail. However, I won't get the usual validation errors on the Flight form (e.g. error message, form fields with errors highlighted) since Flight's problem is that the airline_id (which isn't directly on the Flight form) isn't present, rather than that airline_iata in the Flight form is invalid.
How can I set it up so that this form field that has to interact with the Airport model before submission can run the Airport model's validation on a Flight form field, and return form validation errors accordingly?
You can try to use nested form attributes and add before_validation hook which will override the association:
<%= f.fields_for :airline do |airline_form| %>
<%= airline_form.label :iata_code, "Airline code" %>
<%= airline_form.text_field :iata_code %>
<% end %>
In flight.rb you should have
accept_nested_attributes_for :airline
before_validation :check_existing_airline, on: :create
def check_existing_airline
if airline.new_record? && existing_airline = Airline.find_by(iata_code: airline.iata_code)
self.airline = exisitng_airline
end
end

AssociationTypeMismatch with Rails form using Simple_form

Hello everyone: I'm trying to solve a problem with my form.
I have a product model where every product has one brand.
I'm using simple_form to create/update my products. In my original version I use
= simple_form_for [:admin, product] do |form|
...
= form.association :brand
...
Now I add a jquery select with ajax data loading and I change my input to:
= form.input_field :brand, input_html: { class: 'form-control select2' }
When I save my form I have an error:
ActiveRecord::AssociationTypeMismatch in Admin::ProductsController#create
Brand(#70355202593700) expected, got String(#70355134114860)
In my post params 'brand' is now a string equivalent to the ID of the brand I associate to my product, and I don't know how to fix the association.
Any hint?
For your input_field, it would probably need to be :brand_id because it's no longer being built as an association (that only works with the .association method).
If you are on Rails 3, be sure :brand_id is added to your model's attr_accessible expression.

Rails 4 + ActiveAdmin: Attribute limited to a few values -- customizing ActiveAdmin form based on this?

So I have a CareerEntry model that has a fullintern attribute, which is a string that is supposed to specify whether the entry represents an internship or a full-time position. I limit the values that can appear in this attribute as follows:
validates_inclusion_of :fullintern, :in => ["Internship", "Full-time"]
However, in ActiveAdmin, the part in the edit form that deals with the fullintern attribute still has a text field. How do I make it a dropdown box where the admin can select either "Internship" or "Full-time"?
Thanks.
You can use Formtastic's input helpers to use a select input:
form do |f|
f.inputs "Details" do
f.input :fullintern, as: :select, collection: ["Internship", "Full-time"]
end
f.actions
end
See Formtastic's usage section for the full set of native capabilities.

Rails Simple Form - Error in dropdown input when selecting prompt message

I am using Rails 4 and Simple Form to create a form where I ask users for a bunch of data. I am including a dropdown selector to a model association in the following way:
<%= f.association :location, collection: Location.order("LOWER(name)").all, required: true, include_blank: false, prompt: "Choose location..." %>
However, I get a undefined method 'name' for nil:NilClass error when the user doesn't actively choose anything and leaves the default prompt message selected in the dropdown.
How can I make the app send the user back to the form and highlight that he needs to choose a location in the dropdown? Just like it happens when you have a required input field and no data is provided...
Thanks!
Adding the required: true in your form doesn't actually make the :location a required attribute on your model.
You need to add the following to your model:
validates :location, presence: true

Resources