Jump to content

The ultimate community for Ruby on Rails developers.


Photo

NoMethodError, problems with Model

NoMethodError Model

  • Please log in to reply
3 replies to this topic

#1 E Moloney

E Moloney

    Passenger

  • Members
  • 8 posts

Posted 27 August 2014 - 12:55 PM

Greetings all!

 

I'm a student who's trying to pick up Rails before the next college semester starts. We'll probably be learning it anyway, so I thought that it would be useful to get a handle on it beforehand. I've read over some material, and decided to try my hand at a simple project. The problem is this: I'm having strange problems with one of my Models. The layout of the project is thus:

 

The relevant classes are Card, which contains the attribute name and no other attributes (other than those which Rails generates automatically through create model), and Weapon, which contains the attributes power, durability, and effect. Weapon extends from Card, and so also has the name attribute. The problem comes when I attempt to create a new Weapon: I receive the following error:

undefined method `power' for #<Weapon id: nil, name: nil, created_at: nil, updated_at: nil>
<div class="field">
<%= f.label :power %><br>
<%= f.text_field :power %>
</div>
 
Clearly, the app does not recognize that power is an attribute of weapon, and throws out an error whenever I attempt to instantiate a Weapon. I apologize if this is some obvious newbie mistake, but I'd like to be able to move past this error, and from where I'm standing I can't see how to fix this error. Thanks for your time.


#2 Ohm

Ohm

    Driver

  • Moderators
  • 479 posts
  • LocationCopenhagen

Posted 27 August 2014 - 01:46 PM

Hello, and welcome.

 

It sounds like you're trying to use STI (single-table inheritance) here. With that your Card and Weapon class will live in the same database table, and thus must have all attributes of both present in the table.

 

This will be done like so:

class Card < ActiveRecord::Base
  # ... methods for Card
end

class Weapon < Card
  # ... methods for Weapon
end

If that's the case, you need to create a migration that adds the power, durability, and effect attributes to the Card table.

$ rails g migration AddFieldsToCard power:string durability:string effect:string

You'll also need a type field on the Card model to identify wether an object is a Card or a Weapon.


Blog: http://ohm.sh | Twitter: @madsohm | Work: Lokalebasen.dk


#3 E Moloney

E Moloney

    Passenger

  • Members
  • 8 posts

Posted 27 August 2014 - 02:33 PM

Greetings,

 

I have been thinking about this, and after having looked up what Single-Table Inheritance is, I am not sure that it is the best way of representing the relationship between these models. Weapon is only one of three sub-types of Card that I intended to add to the database, and none of them really has any shared attributes except name, which they inherit from card. They could live in the same table, sure, but there would be a lot of empty spaces, since Card Type B is not meant to have, say, durability, and Card Type B is meant to have an attribute that Weapon does not have. I found a tutorial that stated that Polymorphic Associations were a better way of representing such a relationship than STI, but I'm not sure how this would work.

 

Could you help shine some light on a relationship of this sort? I would also like to apologize for not setting this out more explicitly in advance.



#4 saturnflyer

saturnflyer

    Passenger

  • Members
  • 8 posts

Posted 15 April 2015 - 10:34 PM

Don't use single table inheritance for this.

 

Your Weapon should not inherit from Card.

 

Just make a weapons table and make your Weapon class inherit from ActiveRecord::Base.

 

By inheriting from Card, you're saying that Weapon will behave like and have the same attributes as Card. Clearly it doesn't. The error shows the weapon's "inspect" string

#<Weapon id: nil, name: nil, created_at: nil, updated_at: nil>

And there's no "power" on there. ActiveRecord classes should have their own tables and the columns in the tables will map directly to attributes of the class.

 

Does that help?


Checkout my books: Clean Ruby and Ruby DSL Handbook






Also tagged with one or more of these keywords: NoMethodError, Model

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users