I am creating an action whereby a user can mark homework as complete.
Homework is stored mostly in homework table but homework_student holds the completed_on and a boolean complete attribute:
homework_student.rb
id :integer not null, primary key
# school_user_id :integer not null
# homework_id :integer not null
# completed_on :datetime
# created_at :datetime not null
# updated_at :datetime not null
# complete :boolean
belongs_to :homework, :class_name => 'Homework', :foreign_key => :homework_id, dependent: :destroy
homework.rb
has_many :homework_students, :class_name => 'HomeworkStudent', dependent: :destroy
My attempt...
In my show view for homework I want the user to be able to click complete on their homework and to have the date stored in the completed_on attribute in homework_students.
Routes:
resources :homeworks do
resources :homework_students do
member do
patch :complete
end
end
end
homeworks_controller.rb:
def complete
@complete_item = Homework.homework_students.update_attribute(:completed_on, Time.now)
end
In my view:
<% @homework.homework_students.each do |homework_student| %>
<%= link_to "complete", complete_homework_path(:homework_id => @homework, :home_work_students_id => homework_student), method: :patch %>
<% end %>
I am trying a PATCH method but it is not working. I'm not sure whether it is better to use the boolean attribute for this but i'm not sure how. Homework has many users and each user updates whether they completed or not.
Error:
undefined local variable or method `homework
Much appreciate any guidance.
UPDATE: homeworks_controller.rb
before_action :find_homework, only: [:show, :complete, :edit, :update]
#before_action :set_homework, only: [:show]
#before_action :set_homework_student, except: [:create]
before_action :authenticate_user!
....
def complete
# Loop over each matching homework_student for the @homework where the id matches and update the completed_on attribute.
# You need to get the indivual homework_student record and update it. You could do it other ways but this seemed to work for me.
@homework.homework_students.where(id: params[:home_work_students_id]).each do |homework_student| homework_students.update_attributes(:completed_on => Time.now)
end
# Redirect back to the @homework view.
redirect_to @homework, notice: 'Homework was successfully marked as complete.'
end
....
private
def set_homework_student
@homework_students = HomeworkStudent.find(params[:homework_id])
end
def set_homework
@homework = @homework_students.homeworks.find(params[:id])
end
def homework_params
params.require(:homework).permit(:user_id, :id, :school_user_id, :homeworks, :significance, :significance_id, :sig_option, :feedback_request, :subject, :source, :description, :due, :completed_at, homework_students: [:completed_on, :complete], school_user: [:f_name, :s_name])
end
def find_homework
@homework = Homework.find(params[:id])
end
end
UPDATED ERROR:
Error message:
undefined method `update_attributes' for nil:NilClass
Rails.root:
Application Trace | Framework Trace | Full Trace
app/controllers/homeworks_controller.rb:39:in `block in complete'
app/controllers/homeworks_controller.rb:39:in `complete'
Request
Parameters:
{"_method"=>"patch",
"authenticity_token"=>"OL1vW0BnnJ8TM5lshZWNKisNMrTU2Gp2cY7jYf3T+NRhlx2994q0ndrpehz+vW5unY1EBtSKCHecOJjTDwLHsw==",
"home_work_students_id"=>"142",
"homework_id"=>"78",
"id"=>"78"}
VIEW Update
<% @homework.homework_students.each do |homework_student| %>
<%= link_to "complete", complete_homework_path(@homework, homework_student), method: :patch %>
<% end %>