Reputation: 5001
I'm creating a simple game in Ruby On Rails and I have to create a model whose is referenced by itself.
Look for the example:
class CreateElements < ActiveRecord::Migration
def change
create_table :elements do |t|
t.string :name, limit: 48, null: false, default: ''
t.integer :strong_against, null: false, default: 0
t.integer :weak_against, null: false, default: 0
t.timestamps
end
end
end
There will be some elements in my game such as Fire and Water. Water is weak against lightning but strong against Fire. What I want is reference/associate the model/migration for itself.
I mean, in the view I want to do this:
@element.strong_against.name
I was wondering to create a table called elements_behavior
and on it specify who is strong against who, but I don't know if it is the best way.
Upvotes: 1
Views: 241
Reputation: 76774
I've got a better idea - STI:
#app/models/element.rb
Class Element < ActiveRecord::Base
has_many :element_properties #-> join model
has_many :strengths, -> { where(type: "Strength") } through: :element_properties
has_many :weaknesses, -> { where(type: "Weakness") }, through: :element_properties
#schema id | name | created_at | updated_at
end
#app/models/element_property.rb
Class ElementProperty < ActiveRecord::Base
belongs_to :owner
belongs_to :property
#schema: id | type | element_id | property_id | created_at | updated_at
#type should populate with "Strength" / "Weakness", and then delegate custom actions to STI
end
#app/models/strength.rb
Class Strength < ElementProperty
#Custom actions (power_points? / custom levels?)
end
#app/models/weakness.rb
Class Weakness < ElementProperty
#Custom actions (power_points? / custom levels?)
end
#-> @element.strengths.first.name
#-> @element.weaknesses.first.name
Totally untested, but if you want to use it, we can iterate
Upvotes: 1