Как создать экземпляры ассоциаций дочерних моделей в контроллерах? - PullRequest
1 голос
/ 20 января 2011

Когда я пытаюсь запустить свои функциональные тесты на контроллере для ресурса, называемого «Программы», большинство моих тестов приводят к NoMethodError:

NoMethodError: undefined method `programs' for nil:NilClass

Ресурс Программы имеет отношение own_to наРесурс лагеря, в котором есть множество программ.Исходя из моего опыта в исследовании этой проблемы, все отлично работает в консоли rails, в пользовательском интерфейсе, и все мои модельные тесты проходят.

Почему я получаю эту проблему и как я могу ее исправить?

Вот код, который я использую:

Модель лагеря

class Camp < ActiveRecord::Base

  has_many :contacts
  has_many :sessions
  has_many :programs
  has_many :parents
  has_and_belongs_to_many :campers
  has_one :address, :as => :addressable

  accepts_nested_attributes_for :address, :allow_destroy => true

  validates :name, :presence => true 
  validates :uri, :presence => true, :uniqueness => true
  validates :email_address, :email => true, :allow_nil => true

end

Модель программы

class Program < ActiveRecord::Base

  belongs_to :camp

  has_many :program_populations
  has_many :sessions, :through => :program_populations
  has_and_belongs_to_many :campers, :join_table => "campers_sessions_programs"

  accepts_nested_attributes_for :program_populations

  validates :camp, :presence => true
  validates :name, :presence => true
  validates :min_age, :presence => true, :numericality => {:only_integer => true}
  validates :price, :presence => true, :numericality => true 

end

Метод создания контроллера программ

def create

  @camp = Camp.find_by_uri(params[:camp_id])
  @program = @camp.programs.build(params[:program]) #THIS IS THE PROBLEM AREA

  respond_to do |format|
    if @program.save
      format.html { render :text => "program created!", :status => :created }
      format.xml {render :xml => @program, :status => :created, :location => @program}
    else
      format.html { render :action => "new", :status => :bad_request }
      format.xml  { render :xml => @program.errors, :status => :bad_request }
    end
  end
end

Мой тестовый пример

test "should create program" do
  assert_difference('Program.count') do
    post :create, :program => {
      :camp => camps(:bolo),
      :name => "Test Program",
      :min_age => 10,
      :price => 100.00  
    }
  end

  assert_response :created
  assert_not_nil assigns(:program)

  get :show, :id => assigns(:program).to_param
  assert_response :success
end

Ответы [ 2 ]

2 голосов
/ 20 января 2011

Вы получаете это сообщение об ошибке, потому что @camp равно nil. Это означает, что фактическая ошибка находится в предыдущей строке, Camp.find_by_uri(params[:camp_id]). Проще говоря, Rails не может найти лагерь.

Глядя на свой тест, вы на самом деле не проходите param[:camp_id]. Вместо этого у вас есть параметр param[:program][:camp], который (я полагаю) является всем объектом лагеря. Вместо этого измените свой тест на это:

test "should create program" do
  assert_difference('Program.count') do
    post :create, 
    {:program => {
      :name => "Test Program",
      :min_age => 10,
      :price => 100.00  
    }, 
    :camp_id => camps(:bolo).id}
  end

  assert_response :created
  assert_not_nil assigns(:program)

  get :show, :id => assigns(:program).to_param
  assert_response :success
end

И посмотри, работает ли это.

0 голосов
/ 20 января 2011

Причина вашего теста в том, что он не может найти @camp.Попробуйте передать это в свой тест

post :create, :program => {
  :name => "Test Program",
  :min_age => 10,
  :price => 100.00  
},
:camp_id => camps(:bolo).id

Также, возможно, вы хотите позвонить Camp.find(params[:camp_id]) в свой контроллер?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...