2016-05-13 6 views
0

ich nicht einmal sicher bin, wenn ich ein Problem habe, aber ich mag es einfach nicht, dass meine text_fields und text_areas in der db als empty string statt nil gerettet werden.Schienen text_field/text_ara leerer String vs nil

Ich bin mit den Null-Objekt-Mustern zu spielen und nur realisiert, wenn ich ein Profil erstellen, aber nicht ausfüllen Standortfeld und dann <%= @user.profile.location.upcase %> rufen dann ist es nicht sprengen, da Lage ein String selbst ist es es leer ist .

Ist dies die Schienen-Konvention, um es auf diese Weise zu haben? Wenn ja, warum? Es ist komisch, da etwas sagen wir, es ist ein number_of_pets attr auf das Profil und dann versuche ich so etwas wie

<% if user.profile.number_of_pets.odd? %> 
    <%= @user.profile.first_name %> has odd number of pets 
<% end %> 

nennen es das dann die Luft zu sprengen, da ich nicht nil.odd? nennen kann.

Form wie üblich, so wird es als leere Zeichenfolge gespeichert, wenn nicht

gefüllt
<%= form_for @profile, url: user_profile_path do |f| %> 
    <%= f.label :city %> 
    <%= f.text_field :location, class: 'form-control' %> 
    ...... 
+0

können Sie Validierung für diese –

+0

Amol schreiben, danke für die Antwort, aber das war nicht meine Frage. Ich würde gerne wissen, was die Konvention ist und warum. –

+0

Das hat mich immer auch gestört. Für besser vorhersagbare Daten (leer ist 'NULL') verwende ich immer den' nilify_blanks' Edelstein.Ich weiß, dass das deine Frage nicht beantwortet, aber es ist eher eine Zustimmung. –

Antwort

2

Eine schnelle Abhilfe durch Hinzufügen eines BEFORE_SAVE Rückruf in Ihrem Modell durchgeführt werden können, die alle Werte annimmt, die leer sind und setzt sie zurück zu Null.

In Ihrem Modell zum Beispiel:

before_save :my_nil_maker_method_lol 



    def my_nil_maker_method_lol 
     if self.whatever_attribute.blank? 
     self.whatever_attribute=nil 
     end 
    end 

Update:

Halt von leeren Feldern gespeichert werden könnte mehrere Möglichkeiten, wie oben beschrieben, oder sogar zu löschen leere params in Ihrem Controller durchgeführt werden, bevor sie den Hit Datenbank, aber die Art und Weise, wie Rails die Datenbankintegrität aufrechterhält, besteht darin, diese Logik immer in Ihrem Modell zu halten. Es macht es viel einfacher zu pflegen und lässt viel weniger Raum für Überraschungen, als wenn Sie die eingehenden Parameter woanders ändern würden. So weit wie es in dem Modell getan werden sollte, ist wirklich nur eine Frage dessen, was Sie als Entwickler erwarten, für die Eingabe zu bekommen. Sie können einen Callback hinzufügen, wie oben gezeigt, der Ihre Datenbank so verwaltet, wie Sie es für richtig halten, oder Sie können eine "validates_presence_of" Validierung hinzufügen, die einen Fehler an den Benutzer zurückgibt, wenn dieses Feld leer gelassen wird. Wenn Sie fragen, ob Sie leere Strings überhaupt nicht in die Datenbank einfügen sollten, liegt es wirklich an Ihnen als Entwickler, da es Fälle geben mag, in denen Sie diese Informationen möchten, aber in diesem Fall klingt es wie Sie suche nach leeren Strings.

+0

bkunzi01 danke für die Antwort, aber das war nicht meine Frage. Ich fragte, was ist die Konvention und warum. –

+0

Entschuldigung, ich werde meine Antwort aktualisieren. – bkunzi01

+1

Ich werde es einfach so behalten, wie es vorerst ist. Im Moment brauche ich keine speziellen Sachen, dachte nur, dass ich etwas verpasst habe. –

1

Ich spreche von dem, was ich beobachtet habe, und muss nicht unbedingt die Rails-Konvention.

Wenn wir rails g post title content:text zum Beispiel tun, können Sie sich daran erinnern, dass es nicht default: '' für beide Titel hat (string) und Inhalt (Text). Dies ist für mich bereits ein Hinweis darauf, dass es diesbezüglich keine Rails-Konvention gibt, oder spezifisch gesagt, dass jedes Attribut standardmäßig NULL oder NULL sein darf.

Der Vorteil der Verwendung von NULL besteht darin, dass Sie feststellen können, für welche Datensätze diese Attribute eingerichtet sind.

Nehmen wir an, wir haben einen API-Server. Wenn ein Client einen Post auf unserem API-Server erstellt, wissen wir, welche Attribute einen Wert haben sollen.Sagen wir mal so etwas wie die folgenden:

Client-1 POST params:

post: {title: 'Foo bar'} 
  • wenn NULL-zulässig, erstellt eine Post(title: 'Foo bar', content: nil)
  • wenn default: '', eine Post(title: 'Foo bar', content: '')
  • schaffen

Client-2 POST params:

post: {title: 'Foo bar', content: ''} 
  • wenn NULL-zulässig, wird eine Post(title: 'Foo bar', content: '')
  • erstellen, wenn Standard: '', wird ein Post(title: 'Foo bar', content: '')

Von oben schaffen, feststellen, dass, wenn wir Standard haben: '', dann können wir nicht wissen, wenn der Client tatsächlich einen leeren content Wert haben möchte, weil für client-1 und client-2 der resultierende content Wert für den Post sowieso '' (leer) ist. Aber wenn wir NULL-erlaubte Attribute haben, können wir immer noch identifizieren, ob der Client keinen content Wert haben wollte, indem er das Attribut in den Parametern nicht eingibt. Dies ist ein wichtiger Anwendungsfall.

Abhängig von Ihrem Projekt und dem Zweck des Attributs können Sie entweder NULL-zulässig verwenden oder eine leere Standardzeichenfolge für dieses Attribut festlegen.

Nun, das ein Hauptproblem bei der NULL-zulässig, wie Sie festgestellt haben, ist, dass Sie nicht garantieren können, dass jeder Wert ein String sein wird, deshalb Ihr <%= @user.profile.location.upcase %> einen Fehler in Fall erhöhen location NULL oder null ist.

Dies kann ein wenig lästig sein, besonders wenn man

<%= @user.profile.location.upcase.downcase %> 

Dies wird ein Problem sein, wenn @user.profile.location nil eine Kette von Methoden wie Ihr Beispiel hat, weil Sie anmutig werden müssen, um sicherzustellen, dass es ‚gewonnen t einen Fehler melden. Und das wird auch ein Problem sein, wenn @user.profile ist Null (lassen Sie uns einfach sagen, Sie lassen @user.profile zu Null sein). Und in der Regel werden Sie so etwas wie die folgenden tun, um diese Arbeit zu machen:

<% if [email protected]? && [email protected]? %> 
    <%= @user.profile.location.upcase.downcase %> 
<% end %> 

Der if Zustand kann noch weitergehen sehr lange, wie Sie länger angekettet Methoden muß anmutig sicherzustellen, dass es nicht einen Fehler machen.

Verwenden Sie .try() wird möglicherweise "sauber" dies. Ich benutze das oft in Vorlagendateien. Lösung wird sauberer sein wie unten, wenn auch möglicherweise für diejenigen verwirrend, die nicht wissen:

<%= @user.profile.try(:location).try(:upcase).try(:downcase) %> 

Wenn entweder .location oder .upcase Null ist, wird es Null zurück und keine undefined method ... for NilClass mehr erhöhen.

+0

Dank Jay-Ar, mag ich nicht benutze entweder 'if' oder' try', darum spiele ich mit 'null object pattern'. Aber ich werde die Standardeinstellungen für die Felder beibehalten. –

+0

Gern geschehen! Viel Glück :) –