rails 3 has_and_belongs_to_many NoMethodError неопределенный метод `each 'для nil: NilClass

У меня две модели User и Conf. У них has_and_belongs_to_many отношения. При создании нового объекта conf я хочу назначить его нескольким существующим пользователям, но получил эту ошибку:

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

Это мои модели:

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

Это 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

И вот новый.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 %>

person kalahari    schedule 10.09.2013    source источник


Ответы (1)


Вы не устанавливаете переменную экземпляра @users в действии create, поэтому она оценивается как nil и вызывает ошибку, если вы пытаетесь вызвать для нее each. Это происходит только в том случае, если ваша запись не сохраняется, потому что ваш контроллер затем отображает new частично.

Это должно работать:

  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
person Marek Lipka    schedule 10.09.2013
comment
Спасибо, эта решенная ошибка. Но знаете ли вы, почему моя запись не сохраняется? Прежде чем я добавляю каждую часть, она работала хорошо. - person kalahari; 10.09.2013
comment
@kalahari Думаю, вам следует отладить его и попробовать позвонить @conf.errors.full_messages, чтобы узнать, какие ошибки проверки помешали сохранению вашей записи. - person Marek Lipka; 10.09.2013
comment
Я нашел это в validates_presence_of :users строке в Conf.rb. Когда я удаляю его, запись conf сохраняется, но не назначается никому из пользователей, а confs_users таблица в базе данных не изменяется. Я думаю, что забыл что-то где-то назначить, но не знаю что и где. - person kalahari; 10.09.2013