I’m trying to use composed_of within my model. I have a field in my
database named ‘card1’, which is simply a string. I have this in my
model
class Player < ActiveRecord::Base
composed_of :card1, :class_name => ‘Card’
end
class Card
attr_reader :value, :suit
def initialize(s)
@value = s[0].chr
@suit = s[1].chr
end
end
The accessor method works fine…in my fixture I have a Player created
with card1: As, and I can do
players(:first).card1.suit # => ‘s’
But I can’t assign it:
players(:first).card = nil
Causes
NoMethodError: You have a nil object when you didn’t expect it!
The error occured while evaluating nil.card1
(eval):3:in card1=' test/unit/player_test.rb:51:in
test_validate_cards’
There is no validation for card1 in the Player class. For some reason
I simply can’t assign card1. What am I doing wrong?
Pat
On Mar 18, 2006, at 10:04 PM, Pat M. wrote:
But I can’t assign it:
players(:first).card = nil
I think that should be:
players(:first).card1 = nil
I’m sort of guessing that’s an email typo, though.
I wouldn’t be surprised if composed_of assignment
expects a composed_of object on assignment, i.e.
it wants to assign a Card object, not a nil object.
–
– Tom M.
On 3/19/06, Tom M. [email protected] wrote:
class Card
players(:first).card1.suit # => ‘s’
I wouldn’t be surprised if composed_of assignment
Yeah, that’s just an email typo. Anyway, setting it to a Card object
isn’t any better…
players(:first).card1 = Card.new ‘Jd’
results in
- Error:
test_validate_cards(PlayerTest):
NoMethodError: undefined method card1' for #<Card:0x227263c @suit="d", @value="J"> (eval):3:in
card1=’
test/unit/player_test.rb:51:in `test_validate_cards’
It’s obviously parsing the suit and rank fine…I don’t understand what
the problem is.
Pat
On 3/19/06, Pat M. [email protected] wrote:
with card1: As, and I can do
http://lists.rubyonrails.org/mailman/listinfo/rails
@suit=“d”, @value=“J”>
(eval):3:in card1=' test/unit/player_test.rb:51:in
test_validate_cards’
It’s obviously parsing the suit and rank fine…I don’t understand what
the problem is.
Pat
I’ve kind of gotten around it…I made another attribute in the Card
class named create_str, and did the mapping as
composed_of :card1, :class_name => ‘Card’, :mapping => %w(card1
create_str)
The Card class looks like
class Card
attr_reader :suit, :rank, :create_str
def to_s
“#{@rank}#{@suit}”
end
def initialize(create_str)
@create_str = create_str
@rank = create_str[0].chr
@suit = create_str[1].chr
end
end
I still can’t set card1 to nil though. I want to be able to make it
nil though, so I’m not really sure what to do.
composed_of looked like it’s what I needed, but I’m basically unable
to figure it out…
Pat
On 3/19/06, Pat M. [email protected] wrote:
end
The accessor method works fine…in my fixture I have a Player created
I’m sort of guessing that’s an email typo, though.
[email protected]
NoMethodError: undefined method `card1’ for #<Card:0x227263c
I’ve kind of gotten around it…I made another attribute in the Card
composed_of looked like it’s what I needed, but I’m basically unable
to figure it out…
Pat
Well here’s my solution. It’s kind of ugly and it bugs me that it’s
so un-Railsy…but I don’t know of a better way. I’d appreciate input
from anyone else.
Pat
def card1
if self[:card1].nil? || self[:card1] == ‘’
nil
else
@card1_card ||= Card.new self[:card1]
end
end
def card1=(c)
@card1_card = c
self[:card1] = “#{c}”
end
def card2
if self[:card2].nil? || self[:card2] == ‘’
nil
else
@card2_card ||= Card.new self[:card2]
end
end
def card2=(c)
@card2_card = c
self[:card2] = “#{c}”
end