Or, that is what seems to be happening. I'm getting errors in my production environment that i can't recreate in development. Basically, i'm trying to associate a Booker to a Booking. If the Booker doesn't exist I'd like to invite him/her.
# GET /bookings/new
def new
@booking = Booking.new
authorize @booking
@booking.venue = Venue.new
@booker = User.new
end
Relevant create code;
def create
@booking = Booking.new(booking_params)
authorize @booking
booker_found = set_booker
And the set_booker private method
def set_booker
logger.info "booker: #{booking_params.inspect}"
# set existing user as booker or prepare inviting a new user
booker_found = false
@booker = User.find_by_email(booking_params[:user][:email])
etc.
The last line is where I get errors in production, because booking_params[:user]
does not exist. I tried resetting my database in the development ENV and the code works fine. Yet in production I will always get NoMethodError (undefined method '[]' for nil:NilClass)
This is my relevant form code;
<%= simple_form_for(@booking, :wrapper => :bootstrap3 ) do |f| %>
<%= f.simple_fields_for @booker do |user_form| %>
<%= user_form.input :email, label: "Booker e-mail" %>
<% end %>
This is what logger shows in development;
Parameters: {"utf8"=>"✓", "authenticity_token"=>"lala", "booking"=>{"name"=>"Mah Booking", "date"=>"02-10-2014", "venue_name"=>"Meeeeeeeeeeee", "venue_id"=>"", "user"=>{"email"=>"booker@boekkoek.nl"}, "artist_fee"=>"0.00"}, "commit"=>"Create Booking", "locale"=>"en"}
booker: {"date"=>"02-10-2014", "name"=>"Mah Booking", "artist_fee"=>"0.00", "venue_id"=>"", "venue_name"=>"Meeeeeeeeeeee", "user"=>{"email"=>"booker@boekkoek.nl"}}
And this is from my production.log
Parameters: {"utf8"=>"✓", "authenticity_token"=>"yada", "booking"=>{"name"=>"tttt", "date"=>"02-10-2014", "venue_name"=>"meee", "venue_id"=>"", "user"=>{"email"=>"info@blabl.nl"}, "artist_fee"=>"0.00"}, "commit"=>"Create Booking", "locale"=>"en"}
booker: {"name"=>"tttt", "date"=>"02-10-2014", "artist_fee"=>"0.00", "venue_id"=>""}
I have no idea why the order is different, also, it seems to but "cutting off" after the venue_id, which is obviously causing the error. Has anyone seen behavior like this before?
Edit: Here's my booking_params private method
def booking_params
params.require(:booking).permit(*policy(@booking || Booking).permitted_attributes)
end
And the pundit policy;
def permitted_attributes
[:status,
:date,
:name,
:get_in_time_string,
:soundcheck_time_string,
:dinner_time_string,
:show_time_string,
:show_time_end_string,
:artist_fee,
:venue_id,
:venue_name,
:act_ids => [],
user: [ :id, :email ]
]
end
Like I said, same code works fine in development. The only way I can sort of reproduce the problem is by removing the user params from my permitted_attributes
method, but then I actually get an "unpermitted parameters" error. What would be the right way to define the permitted attributes for "user"? Totally lost on this one.