routes.rb:
resources :courses, path: '' do
resources :students do
resources :awards
end
end
students/show.html.erb
<%= form_for [@course, @student, @award] do |f| %>
<div class="field">
<%= f.label :ticket %><br>
<%= f.text_field :ticket %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
models/student.rb
belongs_to :course
has_many :awards, dependent: :destroy
extend FriendlyId
friendly_id :uuid, use: [ :slugged, :finders ]
controllers/students_controller.rb
before_action :set_course
def show
@student = @course.students.find_by_uuid! params[:id]
@award = @student.awards.build
@awards = @student.awards.load.where.not('id' => nil) # exclude empty row
end
private
def set_course
@course = Course.find_by_title!(params[:course_id])
end
def student_params
params.require(:student).permit(:email, :uuid, :grade_point_average, :course_id)
end
controllers/awards_controller.rb
before_action :set_variables
def create
@award = @student.awards.build award_params
if @award.save
redirect_to course_student_path(@course, @student.uuid)
else
redirect_to course_student_path(@course, @student.uuid)
end
end
private
def set_variables
@course = Course.find_by_title! params[:course_id]
@student = @course.students.find_by_uuid! params[:student_id]
end
def award_params
params.require(:award).permit(:ticket, :student_id)
end
Now, I would expect my POST request sent from the form to look like this:
POST "/3344-2334/students/hh36-f4t4-545t/awards"
But this is what the server is getting
POST "/3344-2334/students/5/awards"
From which I receive an error:
ActiveRecord::RecordNotFound in AwardsController#create
Because it gets the :id (5) instead of the friendly_id :uuid (hh36-f4t4-545t).
Why is the parent (courses) getting a friendly_id :title but the child (students) getting the unfriendly :id? I am new to Rails and completely lost.
You can override the default returned param for the student model to give you the uuid instead of the id. Try put this in your student model.
you can also take a look at this, it may help you understand how friendlyId works.