Frage

Ich bin mit Single Table Inheritance für verschiedene Arten von Projekten zu verwalten. Ich beschloss, einige Informationen mit jedem Projekt Typ zugeordnet zu speichern. Also habe ich neue Tabelle „project_types“ mit „model_type“ Feld als Primärschlüssel. Primärschlüsselwerte sind Werte von „Typ“ Bereich „Projekte“ Tabelle. Problem : Wenn ich mit Project-Objekt ProjectTypes zugeordnet versuchen, erhalten Objekt, das es immer null zurück.

>> p = Project.find(:first)
=> #<SiteDesign id: 1, type: "SiteDesign", name: "1", description: "dddd", concept: "d", client_id: 40, created_at: "2009-10-15 08:17:45", updated_at: "2009-10-15 08:17:45">
>> p.project_type
=> nil

Erste Projekte im Zusammenhang mit ProjectTypes Projekt ist OK. Gibt es so funktioniert es richtig zu machen?

Modelle:

class Project < ActiveRecord::Base
    belongs_to :project_type, :class_name => "ProjectTypes", :foreign_key => "model_name"
end

class SiteDesign < Project
end

class TechDesign < Project
end

class ProjectTypes < ActiveRecord::Base
  self.primary_key = "model_name"
  has_many :projects, :class_name => "Project", :foreign_key => "type"
end

Migrationen:

class CreateProjectTypes < ActiveRecord::Migration
  def self.up
    create_table :project_types, :id => false  do |t|
      t.string :model_name , :null => false
      t.string :name, :null => false
      t.text :description

      t.timestamps
    end

    add_index :project_types, :model_name, :unique => true


    #all project types that are used.
    models_names = {"SiteDesign" => "Site design",
      "TechDesign" => "Tech design"}

    #key for model_name and value for name
    models_names.each do |key,value|
      p = ProjectTypes.new();
      p.model_name = key
      p.name = value
      p.save
    end

  end

  def self.down
    drop_table :project_types
  end
end

class CreateProjects < ActiveRecord::Migration
  def self.up
    create_table :projects do |t|
      t.string :type
      t.string :name
      t.text :description
      t.text :concept
      t.integer :client_id

      t.timestamps
    end
  end

  def self.down
    drop_table :projects
  end
end
War es hilfreich?

Lösung

Kein Wunder, Sie bekommen Probleme. Durch die Bewegung von einem reinen STI-System zu Ihrem aktuellen System brechen Sie schrecklich die Muster, die Sie verwenden, um Teile eines mit Teilen eines anderen Verwirbelung.

ich persönlich für etwas gehen würde wie:

class Project < ActiveRecord::Base
    attr_readonly(:project_type)
    belongs_to :project_type
    before_create :set_project_type

    def set_project_type()
        project_type = ProjectType.find_by_model_name(this.class)
    end
end

class SiteProject < Project
end

class TechProject < Project
end

class ProjectType < ActiveRecord::Base
    has_many :projects
end

mit Migrationen:

class CreateProjectTypes < ActiveRecord::Migration
  def self.up
    create_table :project_types  do |t|
      t.string :model_name , :null => false
      t.string :name, :null => false
      t.text :description

      t.timestamps
    end

    add_index :project_types, :model_name, :unique => true


    #all project types that are used.
    models_names = {"SiteDesign" => "Site design",
      "TechDesign" => "Tech design"}

    #key for model_name and value for name
    models_names.each do |key,value|
      p = ProjectTypes.new();
      p.model_name = key
      p.name = value
      p.save
    end

  end

  def self.down
    drop_table :project_types
  end
end

class CreateProjects < ActiveRecord::Migration
  def self.up
    create_table :projects do |t|
      t.string :type
      t.references :project_type, :null => false
      t.text :description
      t.text :concept
      t.integer :client_id

      t.timestamps
    end
  end

  def self.down
    drop_table :projects
  end
end

Es reinigt nur die Dinge, und es hilft auch zu klären, was Sie tun. Ihr 'Projecttisch rein für zusätzliche Daten ist, Ihr Vererbungsbaum noch existiert. Ich habe auch in einigen Prüfungen geworfen sicher, dass Ihr Projekt Typ immer gesetzt (und richtig, auf der Grundlage der Modellname) und stoppt Sie vom Projekttyp zu ändern, sobald es nur, indem sie das Attribut gelesen gespeichert worden ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top