it-swarm.com.de

Rails Modell ohne Datenbank

Ich möchte ein Rails (2.1 und 2.2) -Modell mit ActiveRecord-Validierungen erstellen, aber ohne Datenbanktabelle. Was ist der am häufigsten verwendete Ansatz? Ich habe einige Plugins gefunden, die behaupten, dies anzubieten Funktionalität, aber viele von ihnen scheinen nicht weit verbreitet zu sein oder werden nicht gewartet. Was empfiehlt die Community? Im Moment neige ich dazu, eine eigene Lösung zu entwickeln, die auf diesem Blog-Beitrag basiert.

64
FlipFlop

Ich denke, der Blog-Post, den Sie verlinken, ist der beste Weg. Ich würde nur vorschlagen, die gestubten Methoden in ein Modul zu verschieben, um Ihren Code nicht zu verschmutzen.

8
Honza

Es gibt eine bessere Möglichkeit, dies in Rails 3: http://railscasts.com/episodes/219-active-model zu tun

67
d135-1r43

Dies ist ein Ansatz, den ich in der Vergangenheit verwendet habe:

In app/models/tableless.rb

class Tableless < ActiveRecord::Base
  def self.columns
    @columns ||= [];
  end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default,
      sql_type.to_s, null)
  end

  # Override the save method to prevent exceptions.
  def save(validate = true)
    validate ? valid? : true
  end
end

In app/models/foo.rb

class Foo < Tableless
  column :bar, :string  
  validates_presence_of :bar
end

In Skript/Konsole

Loading development environment (Rails 2.2.2)
>> foo = Foo.new
=> #<Foo bar: nil>
>> foo.valid?
=> false
>> foo.errors
=> #<ActiveRecord::Errors:0x235b270 @errors={"bar"=>["can't be blank"]}, @base=#<Foo bar: nil>>
43
John Topley

Es gibt jetzt einen einfacheren Weg:

class Model
  include ActiveModel::Model

  attr_accessor :var

  validates :var, presence: true
end

ActiveModel::Model Code:

module ActiveModel
  module Model
    def self.included(base)
      base.class_eval do
        extend  ActiveModel::Naming
        extend  ActiveModel::Translation
        include ActiveModel::Validations
        include ActiveModel::Conversion
      end
    end

    def initialize(params={})
      params.each do |attr, value|
        self.public_send("#{attr}=", value)
      end if params
    end

    def persisted?
      false
    end
  end
end

http://api.rubyonrails.org/classes/ActiveModel/Model.html

19
hlcs

erstellen Sie einfach eine neue Datei mit der Endung ".rb" in Ihrem Verzeichnis "models /". Der Schlüssel hierbei ist, dass Sie Ihr Modell nicht von ActiveRecord erben (da Sie die Datenbankfunktionalität über AR erhalten). Beispiel: Erstellen Sie für ein neues Modell für Autos eine Datei mit dem Namen "car.rb" in Ihrem Modell-/Verzeichnis und in Ihrem Modell:

class Car
    # here goes all your model's stuff
end

edit: btw, wenn du Attribute für deine Klasse haben willst, kannst du hier alles verwenden, was du in Ruby verwendest. Füge einfach ein paar Zeilen mit "attr_accessor" hinzu:

class Car
    attr_accessor :wheels # this will create for you the reader and writer for this attribute
    attr_accessor :doors # ya, this will do the same

    # here goes all your model's stuff
end

edit # 2: Nachdem Sie Mikes Kommentar gelesen haben, würde ich Sie auffordern, seinen Weg zu gehen, wenn Sie die gesamte Funktionalität von ActiveRecord, aber keine Tabelle in der Datenbank möchten. Wenn Sie nur eine gewöhnliche Ruby Klasse wollen, vielleicht finden Sie diese Lösung besser;)

8
tpinto

Der Vollständigkeit halber:

Rails (ab V5) verfügt jetzt über ein praktisches Modul, das Folgendes umfassen kann:

include ActiveModel::Model

Auf diese Weise können Sie mit einem Hash initialisieren und unter anderem Validierungen verwenden.

Vollständige Dokumentation ist hier .

5
xmjw

Es gibt ein Screencast über ein nicht aktives Record-Modell, das von Ryan Bates erfunden wurde. Ein guter Ausgangspunkt.

Nur für den Fall, dass Sie es noch nicht gesehen haben.

4
Laurent Farcy

Ich habe ein schnelles Mixin erstellt, um dies zu handhaben, wie von John Topley vorgeschlagen.

http://github.com/willrjmarshall/Tableless

3
Will Marshall

Was ist mit der Kennzeichnung der Klasse als abstrakt?

class Car < ActiveRecord::Base
  self.abstract = true
end

dies wird Rails dass die Car-Klasse keine entsprechende Tabelle hat.

[bearbeiten]

das wird dir nicht wirklich helfen, wenn du etwas tun musst wie:

my_car = Car.new
2
Mike Breen

Jeder hat jemals versucht, ActiveRecord::Validations und ActiveRecord::Validations::ClassMethods in einer nicht aktiven Record-Klasse und sehen, was passiert, wenn Sie versuchen, Validatoren einzurichten?

Ich bin sicher, dass es viele Abhängigkeiten zwischen dem Validierungsframework und ActiveRecord selbst gibt. Möglicherweise gelingt es Ihnen jedoch, diese Abhängigkeiten zu beseitigen, indem Sie Ihr eigenes Validierungsframework aus dem AR-Validierungsframework entfernen.

Nur eine Idee.

pdate: oopps, das ist mehr oder weniger das, was in dem mit deiner Frage verknüpften Beitrag vorgeschlagen wird. Entschuldigen Sie die Störung.

1
Laurent Farcy

Machen Sie es wie Tiago Pinto gesagt hat und lassen Sie Ihr Modell nicht von ActiveRecord :: Base erben. Es wird nur eine reguläre Ruby Klasse sein, die Sie in eine Datei in Ihrer App/models/directory einfügen. Wenn keines Ihrer Modelle Tabellen enthält und Sie keine Datenbank oder ActiveRecord unter verwenden Stellen Sie sicher, dass Sie in Ihrer Anwendung die Datei environment.rb so ändern, dass sie die folgende Zeile enthält:

config.frameworks -= [:active_record]

Dies sollte innerhalb des Rails::Initializer.run do |config| Block.

0
Sarah Vessels

Sie sollten das PassiveRecord Plugin auschecken. Sie erhalten eine ActiveRecord-ähnliche Schnittstelle für Nicht-Datenbankmodelle. Es ist einfach und unkomplizierter als der Kampf gegen ActiveRecord.

Wir verwenden PassiveRecord in Kombination mit Validatable gem, um das gewünschte Verhalten des OP zu erhalten.

0
Tate Johnson