2009-06-12 13 views
1

Ich bin sicher, dass dies eine völlig offensichtliche Anfängerfrage ist, aber der Versuch, Antworten auf Anfänger Ruby Fragen auf Google zu finden, erweist sich als eine Übung in der Sinnlosigkeit.Ruby Custom Class zu Modell

Wie dem auch sei, nehme ich an eine Datenbanktabelle haben, die wie folgt aussieht:

MyMessage 
================== 
int :id 
string :from 
string :to 
string :messagetext 

Nun, wenn ich eine URL aussetzen müssen, die in Form von in Abfragezeichen params nimmt:

http://mysite.com/?sender=alice&receiver=bob&message=Hello

Was ist der beste Weg, um die Querystring-Parameter zu meinem Modell zuordnen?

Gerade jetzt, ich mache es nur mit brutalen Gewalt in der Steuerung:

@sender = params[:sender] 
@receiver = params[:receiver] 
@message = params[:message] 

@mymessage = MyMessage.new 
@mymessage.from = @sender 
@mymessage.to = @receiver 
@mymessage.messagetext = @message 

@mymessage.save 

Meine Vermutung ist, dass ich in der Lage sein sollte, eine Klasse repräsentiert diese Art von Abfragezeichen Anfrage, dh

zu erstellen
class Request 
    attr_accessor :from 
    attr_accessor :to 
    attr_accessor :message 
end 

dann einige RoR Magie verwenden, um das Request Objekt aus den params und dann mehr Magie zu schaffen, ein Verfahren zu schaffen, bildet das Request Objekt das MyMessage Objekt.

Irgendwelche Vorschläge? Macht das überhaupt Sinn?

+0

Das in so ziemlich jedem des 'my-first-Rails-app' Tutorials abgedeckt ist. Hast du einen gemacht? – fig

+0

Ja, ich habe ungefähr vier davon gemacht. Sind Sie sicher, dass Sie die Frage verstehen? Wenn Sie einen Link veröffentlichen können, der ein Tutorial zeigt, bei dem ich dies verpasst habe, lösche ich die Frage gerne. Ich denke, ich kann es über update_attributes tun, aber die Frage ist aus einem Grund "Neuling" markiert. – jerhinesmith

+0

Ja, ich habe die Beispiel-Apps erstellt. Keiner von ihnen scheint das Erstellen von benutzerdefinierten Klassen und deren Zuordnung zu einem generischen Modell zu behandeln. Ich versuche auch nicht, ein Idiot zu sein, aber verstehst du, dass das Modell/die DB andere Feldnamen/Eigenschaften als das hat, was über die Querystring weitergegeben wird? – jerhinesmith

Antwort

3

Man könnte so etwas tun:

class MyMessage < ActiveRecord::Base 
    def self.new_from_web(params) 
    returning(self.new) do |message| 
     message.from  = params[:sender] 
     message.to   = params[:receiver] 
     message.messagetext = params[:message] 
     message.save 
    end 
    end 
end 

class MessageController < ApplicationController 
    def save_message 
    MyMessage.new_from_web(params) 
    end 
end 

Natürlich ist diese ganze Sache wahrscheinlich unter Verwendung von mehr explizit RESTful Semantik einfacher gemacht und konventionelleren werden könnte.

0

Wenn Sie aktiven Datensatz verwenden, ist die Methode, nach der Sie suchen, update_attributes.

Es wird in etwa so aussehen:

def update 
    @model = Model.find(params[:id]) 
    @model.update_attributes(params[:model]) 
end 

Sie müssen sich bewusst sein, dass dies alles aktualisieren werde der Benutzer geht, einschließlich Felder, die Sie nicht ändern möchten, zum Beispiel ein Flag wie is_admin auf Ihrem Benutzermodell.

Ich schlage vor, die Anwendung attr_accessible auf alle Eigenschaften, die Sie ein Benutzer möchten beispielsweise in der Lage sein zu bearbeiten, zu:

class Model < AR:Base 
    attr_accessible :my_safe_field_name 
end 
+0

Das ist für mich sinnvoll, wenn die übergebenen Felder eine Eins-zu-eins-Abbildung des Modells sind, aber in diesem Fall sind sie nicht (und können nicht sein, da wir wollen, dass das Modell generisch ist und dann entblößt) verschiedene RESTful URLs für Dritte zu konsumieren). Das Modell könnte also "to" haben, aber ein Anbieter könnte es als "Empfänger" übergeben und ein anderer könnte zum Beispiel "sentTo" verwenden. Ich denke, ich muss für jede Implementierung benutzerdefinierte Klassen erstellen und sie dann der generischen Klasse zuordnen, aber ich bin nicht sicher, wie ich das machen soll. Ist das sinnvoll? – jerhinesmith

+0

Nun params [: model] ist nur ein Hash, also könnten Sie immer eine Funktion schreiben, um die Schlüssel so zu ändern, dass sie zu Ihrem Modell passen. Warum können Sie nicht nur eine Darstellung für beide haben? – jonnii

1

Sie etwas tun könnte, wie:

class MessageRequest 
    def initialize(params = {}) 
    @sender = params[:sender] 
    @receiver = params[:receiver] 
    @message = params[:message] 
    end 

    def apply_to_my_message(my_message = MyMessage.new) 
    my_message.from = @sender 
    my_message.to = @receiver 
    my_message.message_text = @message 
    return my_message 
    end 
end 

Dann wird Ihr Controller-Code wird:

@mymessage = MessageRequest.new(params).apply_to_my_message 

Wenn Sie nur für verschiedene benannte Parameter aus verschiedenen anpassen möchten Orte, an denen Sie geschützte Methoden haben könnten, die den Parameternamen für jedes der Attribute zurückgeben. Z.B.

class MessageRequest 
    def initialize(params = {}) 
    @sender = params[sender_param] 
    @receiver = params[receiver_param] 
    @message = params[message_param] 
    end 

    ... 

    protected 

    def sender_param; :sender; end 
    def receiver_param; :receiver; end 
    def message_param; :message; end 
end 

Anschließend können Sie Unterklassen für verschiedene benannte Parameter wie erstellen:

class OtherMessageRequest < MessageRequest 

    protected 
    def receiver_param; :sentTo; end 

end 

wahrscheinlich übertrieben für das, was Sie beschrieben haben, aber hoffentlich, was Sie bekommen bei.

+0

Abgestimmt. Sobald ich es ein bisschen mehr verdaue, wenn es so aussieht, dass es funktioniert, werde ich es akzeptieren. Vielen Dank! – jerhinesmith

0

Einfach geht in der Regel einen langen Weg:

@message = MyMessage.new(params.slice(:sender, :receiver, :message))