cap*_*ome 6 ruby ruby-on-rails nested-forms ruby-on-rails-4
有没有办法可以避免hidden_field将视图中的值传递给控制器的方法?出于安全原因,我更喜欢控制器方法.不幸的@variables是,不支持价值配对strong_parameters.
编辑6/18美国东部时间下午1:00
- 我已将
garages控制器重命名为appointmentscars_controller不再创造新的appointment(正式的garages).在该中创建新约会appointments_controller
我目前的结构
路线
Rails.application.routes.draw做
resources :techs, only: [:index, :show], shallow: true do
resources :cars, only: [:new, :create]
end
Run Code Online (Sandbox Code Playgroud)
资源:约会
#For searchkick
resources :cars, only: [:show] do
collection do
get 'search'
end
end
root "home#index"
end
Run Code Online (Sandbox Code Playgroud)
楷模
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
car.rb
class Car < ActiveRecord::Base
belongs_to :service
belongs_to :tech
has_many :appointments
end
Run Code Online (Sandbox Code Playgroud)
appointment.rb
class Garage < ActiveRecord::Base
belongs_to :customer
belongs_to :tech
belongs_to :car
end
Run Code Online (Sandbox Code Playgroud)
控制器
cars_controller
def new
@car = Car.find(params[:id])
@tech = Tech.find(params[:tech_id])
@appointment = Garage.new
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
意见
cars.new.html
请注意,此表单将隐藏值传递给
appointment_controller.来自
@car.name和其他相似的值不是来自一个text_field预定义的值,而是基于存储在cars数据库中的上一页的选择.
<%= 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 %>
Run Code Online (Sandbox Code Playgroud)
service.html
<%= render 'form' %>
Run Code Online (Sandbox Code Playgroud)
_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 %>
Run Code Online (Sandbox Code Playgroud)
_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>
Run Code Online (Sandbox Code Playgroud)
>编辑美国东部时间下午1点14分
关于该应用程序的这个特定功能的简要概要
customer通过服务列表点击tech所提供的customer选择例如一个服务制动器其是一个服务tech已经在他的个人资料列出.carsdb中cars belongs_to 至 techscustomer可以节省制动器是的一个attribribute techs car到appointmenttech的customer的街道地址,等等,以及car预先加载到form用于在存储appointments表.appointment充当历史表.因此,如果tech决定services在此示例制动器中修改他的任何一个,则appointments表格将保持不受制动器条目的影响.customer选择了Add to appointment按钮,它会保存所有的预定义的值从tech,customer和car属性(在本例中刹车)的appointments分贝.另一种解决方法是strong parameters完全摆脱它并执行以下操作:
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
Run Code Online (Sandbox Code Playgroud)
如果您需要更多详细信息,请与我们联系.
为了解决我的问题,我对最初帖子的最新编辑说明如下:
编辑 6/18 下午 1:00 美国东部时间
- 我已将我的重命名
garages_controller为appointments_controllercars_controller不再创建新的约会(正式车库)。一个新的约会被创建在appointments_controller
我传递的唯一隐藏字段是约会视图 /new.html.erbcar_id中的。 <%= f.hidden_field :car_id, value: @car.id %>
在 中appointments_controller,我分配了car执行以下操作的所有属性。
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
Run Code Online (Sandbox Code Playgroud)
谢谢大家的回复。我应该更清楚。:(