Question

I have two models User and Conf. They have has_and_belongs_to_many relationship. When creating a new conf object, I want to assign it to multiple existing users but I got this error:

NoMethodError in Confs#create
undefined method `each' for nil:NilClass

These are my models:

class User < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation, :developer, :admin, :company_id, :boss_id
  belongs_to :company
  has_and_belongs_to_many :confs

  validates :company_id, presence: true
  validates :boss_id, presence: true
  validates :name,  presence: true, length: { maximum:50 }
end

class Conf < ActiveRecord::Base
  attr_accessible :id, :linear_axis_number, :control_unit_brand, :control_unit_model, :description, 
              :machine_brand, :machine_model, :milling_mode, :rotary_axis_number, :tool_axis_x, :tool_axis_y, 
              :tool_axis_z, :turning_mode, :machine_name, :developer_id, :xml, :users

  validates_presence_of :users
  has_and_belongs_to_many :users
  belongs_to :developer, :class_name => 'User', :foreign_key => 'developer_id'

  has_attached_file :xml, :url => "downloads/:attachment/:id/:basename.:extension", :path => ":rails_root/downloads/:attachment/:id/:basename.:extension"
  attr_protected :xml_file_name, :xml_content_type, :xml_file_size
end

This is confs_controller.rb:

class ConfsController < ApplicationController
  before_filter  :signed_in_user, only:[:index, :edit, :update, :destroy]
  before_filter  :developer_user, only: :destroy

  def new
    @users = User.where(:boss_id => current_user.id)
    @conf = Conf.new
  end

  def create
    @conf = Conf.new(conf_params)    
    if @conf.save
      flash[:success] = "New Configuration uploaded!"
      redirect_to conf_show_own_path
    else
      flash[:error] = "There is a problem!"
      render 'new'
    end
  end

  private
  def conf_params
    params.require(:conf).permit( :id, :linear_axis_number, :control_unit_brand, :control_unit_model, :xml,
                              :description, :machine_brand, :machine_model, :milling_mode, :developer_id,
                              :rotary_axis_number, :tool_axis_x, :tool_axis_y, :tool_axis_z, :turning_mode, 
                              :machine_name, :users) if params[:conf]
  end
end

And here the new.html.erb:

<%= form_for @conf, :html => {:multipart => true} do |f| %>

    <%= f.label :machine_name %>
    <%= f.text_field :machine_name %>
    ....
    <% @users.each do |g| %>
      <%= check_box_tag 'conf[user_ids][]', g.id, false, :id => g.name %>
      <%= label_tag g.name %>
    <% end %>

    <%= f.submit "Upload", class: "btn btn-large btn-primary" %>
<% end %>
Was it helpful?

Solution

You don't set @users instance variable in create action, therefore it evaluates to nil and raises an error if you try to call each on it. It happens only if your record doesn't save because your controller renders new partial then.

This should work:

  def create
    @conf = Conf.new(conf_params)    
    if @conf.save
      flash[:success] = "New Configuration uploaded!"
      redirect_to conf_show_own_path
    else
      @users = User.where(:boss_id => current_user.id)
      flash[:error] = "There is a problem!"
      render 'new'
    end
  end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top