我确信这是一个非常明显的初学者问题,但试图在谷歌上找到初学者Ruby问题的答案,结果证明这是徒劳的。
无论如何,假设我有一个如下所示的数据库表:
MyMessage
==================
int :id
string :from
string :to
string :messagetext
现在,如果我需要以下列形式公开一个接受querystring params的URL:
将查询字符串参数映射到模型的最佳方法是什么?
现在,我只是在控制器内部蛮力地做这件事:
@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
对象的方法。
有什么建议吗?这有意义吗?
答案 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))