I’m trying to update an attribute on a show page, keeping it in the show page, that is connected through a different table. For example: manager logs into admin site and sees several resources, clicks on one and can see all users that have access to the resource (either approved or pending). They can currently delete a user’s access. What I’m trying to do is allow the manager to change the status of the request say from pending to approved.
So for my models I have the following:
class TrainingResource
  has_many :user_training_resources, dependent: :destroy
end
class UserTrainingResource
  belongs_to :user
  belongs_to :training_resource
 enum status: [:pending, :confirmed, :rejected]
end
class Users
  has_many :user_training_resources, dependent: :destroy
  has_many :training_resources, through: :user_training_resources
end
TrainingResourcesController
class Admin::TrainingResourcesController < Admin::ApplicationController
  belongs_to_app :training_resources
  add_breadcrumb 'Training Resources', :admin_training_resources_path
  before_action :load_training_resource, only: [:show, :edit, :update, :destroy]
  respond_to :html, :json
  def index
    @training_resources = TrainingResource.paginate(page: params[:page])
    @training_resources = @training_resources.search(params[:search]) if params[:search]
    respond_with(@training_resources)
  end
  def show
    respond_with @training_resource
  end
  def new
    @training_resource = TrainingResource.new
    respond_with(@training_resource)
  end
  def create
    @training_resource = TrainingResource.new(training_resource_params)
    flash[:notice] = 'TrainingResource created successfully' if @training_resource.save
    respond_with @training_resource, location: admin_training_resources_path
  end
  def edit
    respond_with(@training_resource)
  end
  def update
    flash[:notice] = 'TrainingResource updated successfully' if @training_resource.update(training_resource_params)
    respond_with @training_resource, location: admin_training_resources_path
  end
  def destroy
    flash[:notice] = 'TrainingResource deleted successfully' if @training_resource.destroy
    respond_with @training_resource, location: admin_training_resources_path
  end
  private
  def load_training_resource
    @training_resource = TrainingResource.find_by!(id: params[:id])
  end
  def training_resource_params
    params.require(:training_resource).permit(:name, :description, :total_subscriptions, :url)
  end
end
UserTrainingResourcesController, which is pointing to the TrainingResourcesController
class Admin::UserTrainingResourcesController < Admin::ApplicationController
  belongs_to_app :training_resources
  add_breadcrumb 'Training Resources', :admin_training_resources_path
  before_action :load_training_resource
  respond_to :html, :json
  def edit
    respond_with @user_training_resource
  end
  def update 
    flash[:notice] = 'UserTrainingResource updated successfully' if @user_training_resource.update(user_training_resource_params)
    respond_with @user_training_resource, location: admin_training_resources_path
  end
  def destroy
    flash[:notice] = 'UserTrainingResource deleted successfully' if @user_training_resource.destroy
    respond_with @user_training_resource, location: admin_training_resources_path
  end
  private
  def load_training_resource
    @user_training_resource = UserTrainingResource.find_by!(id: params[:id])
  end
  def user_training_resource_params
    params.require(:user_training_resources).permit(
  :training_resources_id, :status).merge(user_id: current_user_id)
  end
end
Training Resource Show
  <tbody>
    <% @training_resource.users.each do |training| %>
      <tr>
        <td><%= training.full_name %></td>
        <% utr = training.user_training_resources.where(training_resource: @training_resource).first %>
        <td><%= utr.status.capitalize %>
          <%= form_tag '/user_training_resource/edit', :method => :get do %>
            <%= select_tag( :user_training_resources_id, options_for_select(['pending', 'confirmed', 'rejected']))%>
            <%= submit_tag 'Edit Status', class: 'btn btn-default btn-sm' %>
        <% end %>
        <%= tb_form_for [:admin, @training_resource], :remote => true, :data => {:errors => :inline, :success => admin_user_training_resources_path} do |f| %>
          <%= tb_form_errors(f.object, :base) %>
          <%= f.tb_select :name, options_for_select(holder, :status) %>
          <%= f.tb_save_buttons('User Training Resource', admin_user_training_resources_path) %>
        <% end %>
        </td>
        <td class="table-actions">
          <%= link_to 'Edit', edit_admin_user_training_resource_path(training), :class => 'btn btn-default btn-sm' %>
          <%= link_to 'Delete', admin_user_training_resource_path(training), :method => :delete, :data => {:confirm => 'Are you sure you want to delete this?'}, :class => 'btn btn-danger btn-sm'  %>
        </td>
      </tr>
    <% end %>
  </tbody>
User Training Resource Helper, Holder Method
  def holder
    TrainingResource.all.each(&:id)
  end
The link to Edit I’ll end up taking out because it pushes the user to the UserTrainingResource edit page and I want to keep it on the current page. The top form with the select_tag isn’t actually reading in the current status and then the submit_tag is redirecting the page.
My latest attempt is the bottom form_for. This is pulling in the TrainingResource and not the UserTrainingResource data. When I change the tb_select to :status, options_for_select(holder, :status) I end up with undefined method `status’. It looks like it’s only aiming at TrainingResource. I’ve also tried:
Thought here that it would pull in the default status and then allow the options to change. Still have an issue with undefined method of ‘status’ and even then there’s the issues with save.
I’ve also tried:
In this case I end up with undefined method ‘map’. Which I've tried to pinpoint down with attempting pluralization on @training_resource and @user_training_resource but that turns up First argument in form cannot contain nil or be empty.
Edit:
Tried in the UserTrainingResourcesController:
def set_to_confirmed
 @user_training_resource = UserTrainingResource.find(params[:user_training_resource])
end
Then in the show
              <%= link_to 'Confirmed', {:controller => 'user_training_resources', :action => 'set_to_confirmed', :status => @training_resource.user_training_resource }, :class => 'btn btn-default btn-sm'%>
Although no errors on the page load when clicking on the link I get:
Requested URL: https://localhost:3000/admin/set_to_confirmed?status=%23%3CUserTrainingResource%3A%3AActiveRecord_Associations_CollectionProxy%3A0x00007f93ee8b0f90%3E
Latest attempt using the following:
        <% @training_resource.spud_users.each do |training| %>
      <tr>
        <td><%= training.full_name %></td>
        <% utr = training.user_training_resources.where(training_resource: @training_resource).first %>
        <td>
             <%= tb_form_for [:admin, @training_resource], :remote => true, :data => {:errors => :inline, :success => admin_training_resources_path} do |f| %>
               <%= f.select(:user_training_resource_id, options_for_select(['pending', 'confirmed', 'rejected']), :selected => utr.status)%>
               <%= f.tb_save_buttons('', admin_training_resources_path) %>
             <% end %>
        </td>
This will show only the options, which is good, but I need it to default to what's current in the database and the save isn't sticking.
 
    