Monday, August 27, 2018

Rails form drop down select data from database pulled from a different table

Leave a Comment

I have three models that are connected like the following

Users has_many :training_resources, through: :user_training_resources has_many :user_training_resources, dependent: :destroy  TrainingResources has_many :user_training_resource, dependent: :destroy has_many :users, through: :user_training_resource  UserTrainingResources belongs_to :user belongs_to :training_resource 

I'm trying to build out a form on my TrainingResource show page to allow the user to change the status of a UserTrainingResource and it's failed pretty miserably.

This is the latest attempt:

        <% @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.collection_select :user_training_resource_ids, @training_resource, :id, :name %>                <%= f.tb_save_buttons('', admin_training_resources_path) %>              <% end %>         </td>         <td class="table-actions">           <%= 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 %> 

The delete works fine but the select at the moment errors out with: undefined method 'map'.

I've also tried:

<%= f.select(:user_training_resource_ids, UserTrainingResource.pluck(:status, :id))%> 

No error on the page but the options displayed appear to display the current status for ALL UserTrainingResource. Plus it's not actually saving a change.

I've tried:

<%= f.select(:user_training_resource_ids, options_for_select(['pending', 'confirmed', 'rejected'], selected: utr.status))%> 

This actually does present the options because I'm being explicit and it's actually showing the current status. However it's not saving when a selection is made.

Is this just a simple issue of a wrong route? Is there a better way to select data from a different table in a rails drop down?

Edit:

Here's the UserTrainingResources Controller. It's pointing to the TrainingResources Controller's Admin:

class Admin::UserTrainingResourcesController < 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 new    @user_training_resource = UserTrainingResource.new    respond_with @user_training_resource  end    def edit   respond_with @user_training_resource  end   def show    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 

Another edit: Routes

I feel like this is an issue with saving to the correct place so I've included below the routes for user_training_resources:

get '/user_training_resources' => 'user_training_resources#index' delete '/user_training_resources/:id' => 'user_training_resources#destroy', as: :destroy_utr put '/user_training_resources/:id' => 'user_training_resources#update', as: :update_utr 

3 Answers

Answers 1

The issue is actually the form_for being passed to the wrong url. Changed it to reflect a new path url: admin_update_utr_path(utr)

Answers 2

It may well be the route - the route for the form using the POST or PATCH (not sure which) method while your route is expecting a PUT method.

To confirm, check your console to see if the route is resolving to the correct controller action. If not, you can either change the routes to be like:

post '/user_training_resources/:id' => 'user_training_resources#update', as: :update_utr 

or patch '/user_training_resources/:id' => 'user_training_resources#update', as: :update_utr

Answers 3

I think you need to set "multiple" because @training_resource can has many "user_training_resource_ids"

try this :

<%= f.collection_select :user_training_resource_ids, current_user.user_training_resources,                          :id, :name,                          {:prompt => "Please select training resources"},                          {:multiple => true} %> 

source : https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment