Ich möchte ein Rails-Modell (2.1 und 2.2) mit ActiveRecord-Validierungen erstellen, jedoch ohne Datenbanktabelle. Was ist der am weitesten verbreitete Ansatz? Ich habe einige Plugins gefunden, die behaupten, diese Funktionalität anzubieten, aber viele von ihnen scheinen nicht weit verbreitet zu sein oder gewartet zu werden. Was empfiehlt die Community mir? Im Moment neige ich dazu, meine eigene Lösung basierend auf diesem Blog-Beitrag zu entwickeln .
ruby-on-rails
ruby
activerecord
Flip Flops
quelle
quelle
Antworten:
Ich denke, der Blog-Beitrag, den Sie verlinken, ist der beste Weg. Ich würde nur empfehlen, die ausgeblendeten Methoden in ein Modul zu verschieben, um Ihren Code nicht zu verschmutzen.
quelle
In Rails 3 gibt es eine bessere Möglichkeit, dies zu tun: http://railscasts.com/episodes/219-active-model
quelle
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>>
quelle
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
quelle
Erstellen Sie einfach eine neue Datei mit der Endung ".rb" gemäß den gewohnten Konventionen (Singular für Dateiname und Klassenname, unterstrichen für Dateiname, Kamelfall für Klassenname) in Ihrem Verzeichnis "models /". Der Schlüssel hier ist, Ihr Modell nicht von ActiveRecord zu erben (da AR Ihnen die Datenbankfunktionalität bietet). Beispiel: Erstellen Sie für ein neues Modell für Autos eine Datei mit dem Namen "car.rb" in Ihrem Modellverzeichnis und in Ihrem Modell:
class Car # here goes all your model's stuff end
edit: Übrigens, wenn du Attribute für deine Klasse haben willst, kannst du hier alles verwenden, was du für 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 Ihnen sagen, dass Sie seinen Weg gehen sollen, wenn Sie alle Funktionen von ActiveRecord, aber keine Tabelle in der Datenbank haben möchten. Wenn Sie nur eine gewöhnliche Ruby-Klasse wollen, finden Sie diese Lösung vielleicht besser;)
quelle
Der Vollständigkeit halber:
Rails now (bei V5) hat ein praktisches Modul, das Sie einschließen können:
include ActiveModel::Model
Auf diese Weise können Sie mit einem Hash initialisieren und unter anderem Validierungen verwenden.
Die vollständige Dokumentation finden Sie hier .
quelle
Es gibt einen Screencast über ein nicht aktives Rekordmodell, der von Ryan Bates erstellt wurde. Ein guter Ausgangspunkt.
Nur für den Fall, dass Sie es noch nicht gesehen haben.
quelle
Ich habe ein schnelles Mixin erstellt, um dies gemäß John Topleys Vorschlag zu handhaben.
http://github.com/willrjmarshall/Tableless
quelle
Was ist mit dem Markieren der Klasse als abstrakt?
class Car < ActiveRecord::Base self.abstract = true end
Dadurch wird den Schienen mitgeteilt, dass die Fahrzeugklasse keine entsprechende Tabelle hat.
[bearbeiten]
Dies hilft Ihnen nicht wirklich, wenn Sie Folgendes tun müssen:
quelle
Verwenden Sie den validierbaren Edelstein. Wie Sie sagen, gibt es AR-basierte Lösungen, die jedoch tendenziell spröde sind.
http://validatable.rubyforge.org/
quelle
Jeder hat schon einmal versucht , zu schließen
ActiveRecord::Validations
undActiveRecord::Validations::ClassMethods
in einer nicht-Active Record - Klasse und sieht , was passiert , wenn die Einrichtung Validatoren versuchen?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 ableiten.
Nur eine Idee.
Update : oopps, das ist mehr oder weniger das, was in dem mit Ihrer Frage verknüpften Beitrag vorgeschlagen wird. Entschuldigen Sie die Störung.
quelle
Machen Sie es wie Tiago Pinto und lassen Sie Ihr Modell nicht von ActiveRecord :: Base erben. Es ist nur eine reguläre Ruby-Klasse, die Sie in eine Datei in Ihrem Verzeichnis app / models / stecken. Wenn keines Ihrer Modelle Tabellen enthält und Sie in Ihrer App überhaupt keine Datenbank oder ActiveRecord verwenden, müssen Sie Ihre Datei environment.rb so ändern, dass die folgende Zeile angezeigt wird:
config.frameworks -= [:active_record]
Dies sollte innerhalb des
Rails::Initializer.run do |config|
Blocks sein.quelle
Sie sollten das PassiveRecord- Plugin auschecken . Es bietet Ihnen eine ActiveRecord-ähnliche Schnittstelle für Nicht-Datenbankmodelle. Es ist einfach und weniger problematisch als der Kampf gegen ActiveRecord.
Wir verwenden PassiveRecord in Kombination mit dem Juwel Validatable , um das gewünschte Verhalten des OP zu erhalten.
quelle