Ruby / Rails / Rspec - ActiveRecord :: AssociationTypeMismatch: - PullRequest
1 голос
/ 22 декабря 2011

ОК, вот мой rspec-код ...

        before(:each) do
            @attr = { :greeting => "Lorem ipsum", :recipient => @recipient }
        end

        it "should redirect to the home page" do
            puts "spec: @attr = #{@attr}"
            puts "spec: recipient = #{@attr[:recipient]}"
            post :create, :card => @attr
            response.should redirect_to(root_path)
        end

Теперь вывод из этого:

spec: @attr = {:greeting=>"Lorem ipsum", :recipient=>#<User id: 2, first_name: "Example", last_name: "User", email: "recipient@example.com", created_at: "2011-12-22 04:01:02", updated_at: "2011-12-22 04:01:02", encrypted_password: "2d1323ad5eb21fb5ae5e87dfa78a63b521c56833189cc049ee2...", salt: "2679fcc29a30e939541cb98cb65d1d508035fea0eff1136037a...", admin: false>}
spec: recipient = #<User:0xac5d80c>

Итак, мы видим, что получатель - это пользователь.

На стороне контроллера мы видим ...

def create
    puts "create: Params = #{params}"
    @card = current_user.sent_cards.build(params[:card])
    if @card.save
        flash[:success] = "Card created!"
        redirect_to root_path
    else
        render 'pages/home'
    end
end

С дисплеем ...

create: Params = {"card"=>{"greeting"=>"Lorem ipsum", "recipient"=>"2"}, "controller"=>"cards", "action"=>"create"}

и я вижу ошибку ...

1) CardsController POST 'create' success should create a card
   Failure/Error: post :create, :card => @attr
   ActiveRecord::AssociationTypeMismatch:
     User(#90303150) expected, got String(#76171330)
   # ./app/controllers/cards_controller.rb:7:in `create'
   # ./spec/controllers/cards_controller_spec.rb:47:in `block (5 levels) in <top (required)>'
   # ./spec/controllers/cards_controller_spec.rb:44:in `block (4 levels) in <top (required)>'

Итак ... как объект User превратился в его идентификатор в виде строки? Есть идеи?

1 Ответ

1 голос
/ 22 декабря 2011

Вы не можете передать весь объект в качестве параметра. Rails заменяет объект своим идентификатором, если он у него есть, либо передает строковое представление объекта, т.е. #<User:0xac5d80c> для вашего случая, если он не находит идентификатор.

Так что для вашего случая вы должны переименовать параметр: receient в: receient_id. Тогда

@card = current_user.sent_cards.build(params[:card]) 

создаст вашу карту с соответствующим получателем, как мы указали в идентификаторе получателя.

...