Ruby Custom Class для модели - PullRequest
1 голос
/ 12 июня 2009

Я уверен, что это совершенно очевидный вопрос для начинающих, но попытка найти ответы на вопросы начинающих по Ruby в Google оказывается бесполезным упражнением.

В любом случае, предположим, у меня есть таблица базы данных, которая выглядит следующим образом:

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

Теперь, если мне нужно предоставить 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 ]

3 голосов
/ 12 июня 2009

Вы можете сделать что-то вроде этого:

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 голос
/ 12 июня 2009

Вы можете сделать что-то вроде:

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

Если вы просто хотите настроить его для разных именованных параметров из разных мест, у вас могут быть защищенные методы, возвращающие имя параметра для каждого из атрибутов. Э.Г.

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

Вероятно, излишнее из-за того, что вы описали, но, надеюсь, что вы получаете.

0 голосов
/ 17 июня 2009

Простое обычно имеет большое значение:

@message = MyMessage.new(params.slice(:sender, :receiver, :message))
0 голосов
/ 12 июня 2009

Если вы используете активную запись, то вы ищете метод 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...