user.rb
has_many :habits, dependent: :destroy
habit.rb
belongs_to :user
Relationship where user model has multiple habit models The habit model has a string type column called task and an integer type column called complete.
I want to add +1 to the complete column only for the checked habit model Collection_check_boxes can do this at once with one form How to write is like this
<%= form_with(model: @user,url: complete_user_path, local: true) do |f|%>
<h4><%= @user.name %></h4>
<p class="pt-3">Habits</p>
<div class="complete-content">
<%= f.collection_check_boxes :habit_ids, @user.habits,:id,:task,checked: false do |b| %>
<%= b.label do %>
<%= b.check_box %>
<%= b.text %>
<% end %>
<% end %>
</div>
<%= f.submit "Send",class: "btn btn-primary m-5"%>
<% end %>
HTML like below is generated
<input type="hidden" name="user[habit_ids][]" value="">
<label for="user_habit_ids_11">
<input type="checkbox" value="11" name="user[habit_ids][]" id="user_habit_ids_11">
running
</label>
<label for="user_habit_ids_12">
<input type="checkbox" value="12" name="user[habit_ids][]" id="user_habit_ids_12">
programming
</label>
<%= f.collection_check_boxes :habit_ids, @user.habits,:id,:task,checked: false do |b| %>
When disassembling
model: @user's habit_ids Store in this array with name = user [habit_ids] []
@ user.habits Generates as many checkboxes as there are habit models that @user has
: id name = user [habit_ids] [] value to be stored in this case habit.id
: task lavel In this case running, programming
checkd: false For some reason, it was checked by default, so set it to false
When receiving with the controller
def complete_params
params.require(:user).permit(habit_ids: [])
end
29: def complete
30: @user = User.find_by(id: params[:id])
31: before_level = @user.level
32: habit_id = (complete_params)
=> 33: binding.pry
[1] pry(#<UsersController>)> habit_id
=> <ActionController::Parameters {"habit_ids"=>["", "11", "12"]} permitted: true>
I want to extract only the id from here. Completed form
29: def complete
30: @user = User.find_by(id: params[:id])
31: before_level = @user.level
32: habit_id = (complete_params).values.flatten.compact.reject(&:empty?)
=> 33: binding.pry
34: unless habit_id.empty?
35: @habit = Habit.find(habit_id)
36: @habit.each do |h|
37: h.update_attributes(complete: h.complete += 1)
38: @user.update_attributes(level: @user.level += 1)
39: flash[:notice] = "Achieved!"
40: end
43: end
44: @user.level_change(before_level)
45: redirect_to @user
46: end
[1] pry(#<UsersController>)> habit_id
=> ["11", "12"]
It worked, but I wonder if there is a better way
Recommended Posts