# Trouble with composed\_of

**URL:** <https://www.ruby-forum.com/t/trouble-with-composed-of/55295>\
**Category:** Rails\
**Created:** [March 19, 2006, 7:29am UTC](https://www.ruby-forum.com/t/trouble-with-composed-of/55295 "2006-03-19T07:29:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [March 19, 2006, 7:29am UTC](https://www.ruby-forum.com/t/trouble-with-composed-of/55295/1 "2006-03-19T07:29:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [March 19, 2006, 12:17pm UTC](https://www.ruby-forum.com/t/trouble-with-composed-of/55295/2 "2006-03-19T12:17:04Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [March 19, 2006, 12:17pm UTC](https://www.ruby-forum.com/t/trouble-with-composed-of/55295/3 "2006-03-19T12:17:12Z")

</div>

On 3/19/06, Tom M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

1. 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

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [March 19, 2006, 5:27pm UTC](https://www.ruby-forum.com/t/trouble-with-composed-of/55295/4 "2006-03-19T17:27:53Z")

</div>

On 3/19/06, Pat M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > with card1: As, and I can do
> > 
> > [http://lists.rubyonrails.org/mailman/listinfo/rails](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

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [March 19, 2006, 5:47pm UTC](https://www.ruby-forum.com/t/trouble-with-composed-of/55295/5 "2006-03-19T17:47:16Z")

</div>

On 3/19/06, Pat M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.  
> > > > removed\_email\_address@domain.invalid  
> > > > 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
