2

(ゲームのように)クエストのようなもののRailsモデルがある場合、名前、説明、電気ショック療法などの属性があります。ただし、クエストを完了するためにプレーヤーが要件を満たしているかどうかを判断するには、各クエストに関連付けられたコードも必要です。

一部のコードをモデルのレコードに関連付ける最良の方法は何ですか?新しいクエストを作成するときに、モデルにquest_function属性を作成し、models / quest.rbファイルの各レコードに関数を書き込む必要がありますか?これは不格好でエラーが発生しやすいようです。

Railsでこのようなことをどのように行う必要がありますか?

4

2 に答える 2

4

さて、あなたにはいくつかの選択肢があります。

1つ目は、あなたが言ったように、メソッド/関数名をレコードに保存し、そのレコードのクエストが完了したかどうかを評価する必要があるときはいつでもそのメソッドを呼び出すことです。大まかなコード:

class Quest < ActiveRecord::Base
    attr_accessible :name, :quest_method

    def completed?
      self.send(quest_method)
    end

    def end_quest
       Monster.find_by_name('FINAL BOSS').dead?
    end
end

Quest.create name: 'End Quest', quest_method: 'end_quest'

これはあなたが思っているほど悪くはありません。これは基本的に単一テーブル継承の仕組みですが、メソッド名を格納する代わりに、クラス名をtype列に格納します。

class Quest < ActiveRecord::Base

    def finished?
        # default value, or throw an error
        false
    end

end

class EndQuest < Quest

    def finished?
        Monster.find_by_name('END BOSS').dead?
    end
end

EndQuest.create # have to do this for all quests

いずれの場合も、動作をコードとして記述し、目的の動作への参照をレコードに保存するだけです。適切なタイプまたはメソッド名を使用してすべてのレコードを手動で作成し、すべてが同期していることを確認する必要があります。しかし、少なくとも単一テーブル継承では、ActiveRecordがその一部を処理します。

ただし、コード自体をデータベースに保存することを妨げるものは何もありません。

class Quest < ActiveRecord::Base

    attr_accessible :name, :completed_expr

    def completed?
        eval(completed_expr)
    end

end

Quest.create name: 'END QUEST', 
  completed_expr: "Monster.find_by_name('BIG BOSS').dead?"

もちろん、これは潜在的に危険であり、何をしているのかを正確に理解していない限りエラーが発生しやすくなりますが、実行時にクエストの完了基準を書き直す完全な柔軟性が得られます。

最後に、最も洗練された複雑なものが必要な場合は、ルールエンジンを使用して(またはDSLを使用して独自のルールを展開し)、ビジネス(ゲームの世界)ルールを包含して保存することを検討してください。

class Quest < ActiveRecord::Base
    attr_accessible :name, :completion_rule

    def completed?
        RulesEngine.evaluate(completion_rule)
    end
end

Quest.create name: 'END QUEST', 
  completion_rule: "Monster(name: 'BIG BOSS', state: 'dead')"

主な利点は、クエスト固有の動作またはルールをDSL(生のRubyコードではない)に保存することで、ある程度のセキュリティを確保できることです。誤ってeval悪意のあるコードや誤ったコードを作成して家を倒すことはできません。

また、 Reteアルゴリズムなどを使用して評価できるようにプロダクションルールをモデル化すると、効率を上げることができます。

于 2013-01-24T08:13:04.390 に答える
1

クエストが作成されるたびに関数を呼び出したい場合は、after_createafter_updateなどのrailsコールバックを使用する必要があります。

http://guides.rubyonrails.org/active_record_validations_callbacks.html#callbacks-overview

于 2013-01-24T07:38:01.553 に答える