0

I have created a view for volunteers to sign up for specific shifts. I am able to write my view and controller for shifts so that, when the form_for submit button is clicked, the current_user.id is pushed onto the specific shift's user_ids attribute, which is an array. The problem is that it updates each of the shift's user_ids with the current user's id. What am I missing here? Any insight would be appreciated. Thanks.

volunteer.html.erb

<div class="container">
  <div style="width:60%;margin:0 auto 0 auto;" class="inner-lower">

    <div class="list-group">
      <% @uniq_shifts.each do |title| %>

        <% @shifts_by_title = @shifts.where(title: title) %>
        <% @title_vols = @shifts_by_title.pluck(:vols_needed).sum %>
        <% @times = @shifts_by_title.pluck(:time) %>
        <% @time_vols = @shifts_by_title.pluck(:vols_needed) %> 

        <% if @title_vols > 0 %>

          <!-- ACTIVITY TITLE -->
          <div id=<%= "activity#{title}" %> class="activity">

            <a href="#" class="list-group-item">
              <%= title %>
              <!-- ACTIVITY NUMBER VOLUNTEERS NEEDED-->
              <span class="badge-volunteer"><%= @title_vols %></span>
            </a>

          </div>


          <div class="sub" style="display:none;">

            <% @shifts_by_title.each do |shift| %>
              <!-- ACTIVITY SHIFT -->
              <a href="#" class="list-group-item-sub">
            <!-- ACTIVITY SHIFT TIME -->
            <%= shift.time %>
            <span class="badge">
              <!-- ACTIVITY SHIFT NUMBER OF VOLUNTEERS NEEDED -->
              <%= shift.vols_needed %>
            </span>
              </a>

              <%= form_for shift, :method => :put do |f| %>
            <%= f.hidden_field :user_ids, :value => shift.add_user_id(@user.id) %>
            <%= f.submit "sign up", class: "btn btn-primary" %>
              <% end %>

            <% end %>
          </div>


        <% end %>

      <% end %>
    </div>
  </div>

shift.rb

class Shift < ActiveRecord::Base
  has_and_belongs_to_many :users

  def add_user_id(user_id)

    user_ids_will_change!

    update_attributes user_ids: self.user_ids + [ user_id ]
    self.save
  end
end

shifts.controller.rb

class ShiftsController < ApplicationController
  before_action :set_shift, only: [:show, :edit, :update, :destroy]
  before_action :volunteer, only: [:show, :edit, :update, :destroy]

  def index
    @shifts = Shift.all
  end

  def volunteer
    @shifts = Shift.all
    @user = current_user
    @shift_titles = @shifts.pluck(:title)
    @uniq_shifts = @shift_titles.uniq
    @vols_needed = @shifts.pluck(:vols_needed)

    unless current_user
      render action: 'new'
    end

  end

  def show
  end

  def new
    @shift = Shift.new
  end

  def edit
  end

  def create
    @shift = Shift.new(shift_params)

    if @shift.save
      redirect_to @shift, notice: 'Shift was successfully created.'
    else
      render :new
    end
  end

  def update
    @user = current_user

    if @shift.update(shift_params)
      redirect_to @shift, notice: 'Shift was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    @shift.destroy
    redirect_to pages_url, notice: 'Shift was successfully destroyed.'
  end

  private
  # Use callbacks to share common setup or contraints between actions.
  def set_shift
    @shift = Shift.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def shift_params
    params.require(:shift).permit(:title, :time, :vols_needed, :user_ids => [])
  end
end
AnderSon
  • 71
  • 4
  • You need to separate the concerns here: - you're executing your instance class method add_user_id form a controller. Don't do that. Trigger that upon submission of your form. – Lukasz Muzyka Jun 21 '14 at 23:36
  • Sorry, form helpers are a bit confusing to me yet. I thought that the submit button triggered what is called in the hidden field. – AnderSon Jun 22 '14 at 15:26
  • Standard practice is to use form helper to build the form. Than trigger things form the controller and define methods inside model. Let me see if I can answer your question. – Lukasz Muzyka Jun 23 '14 at 00:47
  • As it turns out, and still not sure what is really going on here, the user_ids attribute on each of the Shift records is being updated when the page is refreshed and the button click is not having the effect. – AnderSon Jul 03 '14 at 23:43
  • It would be probably easier to write your code again if you had clear goal in mind. Looks like you're trying to fight against the convention too much up there. Try Commenting to this post with description of your goal - I'll get notification and will try to help you over the weekend if you're still stuck. – Lukasz Muzyka Jul 04 '14 at 03:30
  • There is an event. The event has several activities. Each of these activities need a number of *volunteers*(User) to be present during each *shift*(Shift) that the activity is being run. The view should present the user with a list of shifts that are in need of volunteers along with the number of volunteers needed. The functionality should be such that the user can either click on a button or even the shift itself to "sign up" as a volunteer for that particular shift. The way I have tried to impliment this is by pushing the current user's id onto a Shift array attribute (user_ids). – AnderSon Jul 04 '14 at 14:15
  • Thanks to a recommendation to use Pry for debugging, I was able to determine that the line to create the hidden_field, `<%= f.hidden_field :user_ids, :value => shift.add_user_id(@user.id) %>` is in fact calling `add_user_id(@user.id)` on each shift as each form loads on the page. Why might this happen? Shouldn't that wait for the submit button? – AnderSon Jul 06 '14 at 19:26

0 Answers0