Is there a way I can avoid the hidden_field method of passing values in the view to a controller? I would prefer a controller method for security reasons. Unfortunately value pairing @variables is not supported in strong_parameters.
EDIT 6/18 1:00 PM EST
- I've renamed my
 garagescontroller toappointmentscars_controllerno longer creates a newappointment(formallygarages). A new appointment is created in theappointments_controller
My current structure
routes
Rails.application.routes.draw do
resources :techs, only: [:index, :show], shallow: true do
    resources :cars, only: [:new, :create]
end
resources :appointments
#For searchkick
resources :cars, only: [:show] do
    collection do
        get 'search'
    end
end
root "home#index"
end
models
tech.rb
class Tech < ActiveRecord::Base
    searchkick
    has_many :appointments
    has_many :customers, :through => :appointments
    has_many :service_menus
    has_many :services
    has_many :cars
end
service.rb
class Service < ActiveRecord::Base
    belongs_to :tech
    belongs_to :service_menu
    has_many :cars, dependent: :destroy
    accepts_nested_attributes_for :cars, :reject_if => :all_blank, :allow_destroy => true
end
car.rb
class Car < ActiveRecord::Base  
  belongs_to :service
  belongs_to :tech
  has_many :appointments 
end
appointment.rb
class Garage < ActiveRecord::Base
  belongs_to :customer
  belongs_to :tech
  belongs_to :car
end
controllers
cars_controller
def new
  @car = Car.find(params[:id])
  @tech = Tech.find(params[:tech_id])
  @appointment = Garage.new 
end
appointments_controller
def create
  @appointment = current_customer.appointments.build(appointment_params)
  if @appointment.save
    redirect_to appointments_path, notice:  "You car has been added to this appointment." 
  else
    redirect_to appointments_path, notice:  "Uh oh, an error has occured." 
  end
end
private
def appointment_params
  params.require(:appointment).permit(:tech_id, :service_id, :car_id, ...and a bunch of other keys here)
end
views
cars.new.html
Please note this form passes hidden values to the
appointment_controller.Value from
@car.nameand other alike are not from atext_fieldbut rather a pre-defined value based on selections from a previous page which is store in thecarsdb.
<%= simple_form_for(@appointment, { class: 'form-horizontal' }) do |f| %>
        <%= f.hidden_field :tech_id, value: @tech.id %>
        <%= f.hidden_field :car_id, value: @car.id %>
        <%= f.hidden_field :service_id, value: @car.service.id %>
        <%= f.hidden_field :customer_car, value: current_customer.car %>
        <%= f.hidden_field :customer_street_address, value: current_customer.street_address %>
        <%= f.hidden_field :customer_city, value: current_customer.city %>
        <%= f.hidden_field :customer_state, value: current_customer.state %>
        <%= f.hidden_field :customer_zip_code, value: current_customer.zip_code %>
        <%= f.hidden_field :service_name, value: @car.service.service_menu.name %>    
        <%= f.hidden_field :car_name, value: @car.name %>
    
        <%= **And a bunch of other hidden values here which are too long to list**  %>
    
    <%= f.submit "Add to appointment", class: 'btn btn-default' %>
    <% end %>
service.html
<%= render 'form' %>
_form.html
<%= simple_form_for @service do |f| %>
  <div class="field">
    <%= f.label "Select service category" %>
    <br>
    
    <%= collection_select(:service, :service_menu_id, ServiceMenu.all, :id, :name, {:prompt => true }) %>
    <%= f.fields_for :cars do |task| %>
      <%= render 'car_fields', :f => task %>
    <% end %>
  </div>
  <div class="links">
    <%= link_to_add_association 'Add New Car', f, :cars, class: 'btn btn-default' %>
  </div><br>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
_car_fields.html
<div class="nested-fields">
  <div class="field">
        <%= f.label :name %><br>
        <%= f.text_field :name %><br>
        <%= f.label :hours %>
        <%= f.select :hours, '0'..'8' %>
        <%= f.label :minutes %>
        <%= f.select :minutes, options_for_select( (0..45).step(15), selected: f.object.minutes) %><br>
        <%= f.label :price %><br>
        <%= f.text_field :price, :value => (number_with_precision(f.object.price, :precision => 2) || 0) %> <br>
        <%= f.label :details %><br>
        <%= f.text_area :details %></div>
  <%= link_to_remove_association "Remove Car", f, class: 'btn btn-default' %>
  <%= f.hidden_field :tech_id, value: current_tech.id %>
  <br>
    <hr>
</div>
> Edit 7/14 1:30 pm EST
Brief Synopsis on this specific function of the application
customer clicks through a list of services a tech has to offercustomer selects a service for example brakes which is a service a tech has listed in his profile.cars dbcars belongs_to to techs
customer can save brakes which is an attribribute of a techs car to a appointment
tech, the customer's street address, etc..., and the car are pre-loaded in the form for storing in the appointments table.appointment acts as a histories table. So if the tech decides to modify any one of his services in this example brakes, the appointments tables will remain untouched for the brakes entry.customer selects the Add to appointment button, it will save all of the predefined values from tech, customer, and car attributes (in this example brakes) to the appointments db.Another approach to this would be to get rid of the strong parameters altogether and do the following:
def create
    @appointment = Garage.create(tech_id: @car.service.tech.id,
                                      customer_id: current_customer.id,
                                      customer_street_address: current_customer.street_address,
                                      customer_city: current_customer.city,
                                      customer_state: current_customer.state,
                                      customer_zip_code: current_customer.zip_code,
                                      customer_phone_number: current_customer.phone_number,
                                      customer_location_type: "WILL ADD LATER",
                                      customer_latitude: current_customer.latitude,
                                      customer_longitude: current_customer.longitude,                                      
                                      service_id: @car.service.id,
                                      service_name: @car.service.name,
                                      car_id: @car.id,
                                      car_name: @car.name,
                                      car_time_duration: @car.time_duration,
                                      price: @car.price,
                                      car_details: @car.details)
  
    if @appointment.save
      redirect_to techs_path, notice:  "This service has been saved." 
    elsif 
      redirect_to tech_path, notice:  "Uh oh, an error has occurred." 
    end
  end
Please let me know if you require further details.
I can think of some methods you could use to avoid this form bloated with hidden_fields:
hidden_field in the form.Whichever method you choose, keep in mind that storing a lot of state in a web application usually is a code smell. You can always rethink your application so you don't need to keep so much context.
To resolve my issue, my latest edit from my initial post stated the following:
EDIT 6/18 1:00 PM EST
- I've renamed my
 garages_controllertoappointments_controllercars_controllerno longer creates a new appointment (formally garages). A new appointment is created in theappointments_controller
Only hidden_field i'm passing is the car_id in the appointments view /new.html.erb <%= f.hidden_field :car_id, value: @car.id %>.
In the appointments_controller, I'm assigning all the car attributes doing the following.
def create
    @appointment = current_customer.appointments.build(appointment_params)
    @appointment.tech_id = @appointment.car.service.tech.id
    @appointment.price = @appointment.car.price
    @appointment.car_name = @appointment.car.name
    @appointment.car_details = @appointment.car.details
    if @appointment.save
        redirect_to appointments_path, notice:  "Thank you booking your appointment." 
    else
        redirect_to appointments_path, notice:  "Uh oh, an error has occurred. Please try again or contact us for further assistance" 
    end
end
Thank you all for your responses. I should've known better. :(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With