Ruby Custom Class to Model

时间:2009-06-12 13:45:46

标签: ruby-on-rails ruby

我确信这是一个非常明显的初学者问题,但试图在谷歌上找到初学者Ruby问题的答案,结果证明这是徒劳的。

无论如何,假设我有一个如下所示的数据库表:

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

现在,如果我需要以下列形式公开一个接受querystring params的URL:

  

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

将查询字符串参数映射到模型的最佳方法是什么?

现在,我只是在控制器内部蛮力地做这件事:

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

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

@mymessage.save

我的猜测是我应该能够创建一个代表这种查询字符串请求的类,即

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

然后使用一些RoR魔法从Request创建params对象,然后更神奇地创建一个将Request对象映射到MyMessage对象的方法。

有什么建议吗?这有意义吗?

4 个答案:

答案 0 :(得分:3)

你可以这样做:

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

当然,通过使用更明确的RESTful语义,整个事情可能变得更简单和更传统。

答案 1 :(得分:1)

您可以执行以下操作:

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

然后您的控制器代码变为:

@mymessage = MessageRequest.new(params).apply_to_my_message

如果您只想为来自不同位置的不同命名参数自定义它,您可以使用受保护的方法返回每个属性的参数名称。 E.g。

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

然后,您可以为不同的命名参数创建子类,例如:

class OtherMessageRequest < MessageRequest

  protected
    def receiver_param; :sentTo; end

end

对于你所描述的内容可能有些过分,但希望你得到的是什么。

答案 2 :(得分:0)

如果您正在使用活动记录,那么您正在寻找的方法是update_attributes。

它看起来像这样:

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

您需要注意,这会更新用户传入的任何内容,包括您可能不想更改的字段,例如您的用户模型上的is_admin等标记。

我建议将attr_accessible应用于您希望用户能够编辑的任何属性,例如:

class Model < AR:Base
    attr_accessible :my_safe_field_name
end

答案 3 :(得分:0)

简单通常有很长的路要走:

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