Guilherme Oderdenge
Guilherme Oderdenge

Reputation: 5001

Self-referencing model

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

My thoughts

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

Answers (1)

Richard Peck
Richard Peck

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

Related Questions