RSpec - problem z przekazywaniem atrybutów

Siedzę właśnie nad pierwszą aplikacją robioną zgodnie z założeniami BDD, używając do tego RSpeca. Wszystko było pięknie, dopóki nie natrafiłem na problem, który sprawia, że schzuje i mam ochotę cisnąć komputer przez okno.

Używam pluginu restful authentication, więc model user już był zrobiony. Stwierdziłem, że mimo iż to już nie będzie BDD, to i tak napiszę testy dla tego modelu. Testowanie szło bez żadnych problemów, dopóki nie dodałem dodatkowych pól do usera (to już de facto było BDD):

t.string :card_holder t.string :card_number t.string :ccv2
W modelu mam:

  validates_presence_of  :login, :email, :ccv2, :card_holder, :card_number

W pliku user_spec.rb

[code]
module UserSpecHelper

def valid_user_attributes
{
:email => ‘testowy@email.com’,
:ccv2 => ‘1234’,
:login => ‘testowy’,
:password => ‘password’,
:password_confirmation => ‘password’,
:card_holder => ‘ktos’,
:card_number => ‘1111 2222 3333 4444’,
:ccv2 => “1234”
}
end
end

describe User do
include UserSpecHelper

before(:each) do
@user = User.new
end

it do
@user.attributes = valid_user_attributes
@user.should be_valid
end

end[/code]
I teraz się dzieje rzecz, której nie mogę pojąć. RSpec mi wyrzuca, że valid? powinno być true, a jest false. Gdy usunę validates_presence_of :ccv2, :card_holder, :card_number w modelu, wtedy wszystko bangla i nie ma błędów. Okazuje się, że w tym kawałku kodu:

it do @user.attributes = valid_user_attributes @user.should be_valid end
na usera zostają przypisane tylko niektóre atrybuty z hasha zwracanego przez metodę valid_user_attributes (te, które były stworzone przez restful authentication). Reszta, dodana przeze mnie jest równa nil.

raise @user.attributes.inspect #=>{"salt"=>nil, "updated_at"=>nil, "crypted_password"=>nil, #"remember_token_expires_at"=>nil, "card_holder"=>nil, #"ccv2"=>nil, "card_number"=>nil, "remember_token"=>nil, #"login"=>"testowy", "email"=>"testowy@email.com", "created_at"=>nil}
Co ciekawe, mogę przypisać na te trzy atrybuty wartości w it “should be valid” do w taki sposób:

it do @user.attributes = valid_user_attributes @user.card_holder = 'ktos' @user.card_number = '1111 2222 3333 4444' @user.ccv2 = '1234' @user.should be_valid end
Wtedy wszystko działa. I niby mogę tak to zrobić, ale sam fakt, że nie wiem co się dzieje sprawia, że mnie złość roznosi ;]

Pozdrawiam
sarniak

restful_authentication dodaje do modelu User taką linijkę:

[code=ruby] # prevents a user from submitting a crafted form that bypasses activation

anything else you want your user to change should be added here.

attr_accessible :login, :email, :password, :password_confirmation[/code]
Jak już się zapewne domyślasz musisz dodać Twoje nowe kolumny do tej linii.

Więcej o attr_accessible

Damn… dzięki za odpowiedź…
Jak widać trywialna sprawa, tylko ja się od dupy strony zabierałem do szukania co jest nie tak.
Pozdrawiam

Twój model, albo definiowany przez ten plugin ma po prostu wpis o attr_protected lub attr_accessible (poczytaj w api rails). Gdyby tego nie robił to można byłoby sporo namieszać ;). Jak chcesz przepisać wszystkie atrybuty z tego hasha to zrób sobie jakiś helper do tego, np:

[code=ruby]def fill_attributes(user, attributes)
attributes.each do |key, value|
user.send("#{key}=", value)
end
end

#a potem
fill_attributes(@user, valid_user_attributes)[/code]