1

我的 PushupReminder 控制器中有两个模型UserPushupReminder一个方法create_a_reminder(这是放置它的最佳位置吗?),当我向给定用户传递用户 ID 时,我希望为给定用户创建一个新的 PushupReminder 实例。我通过 user_id 列在我的PushupReminder表中正常工作,并且我已经测试过我可以创建提醒并通过 Rails 控制台正确发送提醒电子邮件。

这是模型代码的片段:

class User < ActiveRecord::Base
    has_many :pushup_reminders
end

class PushupReminder < ActiveRecord::Base
    belongs_to :user
end

和 create_a_reminder 方法:

def create_a_reminder(user)
    @user = User.find(user)

    @reminder = PushupReminder.create(:user_id => @user.id, :completed => false, :num_pushups => @user.pushups_per_reminder, :when_sent => Time.now)

    PushupReminderMailer.reminder_email(@user).deliver
end

我不知道如何create_a_reminder在我的代码中为给定用户运行该方法(最终将在我所有用户的 cron 作业中)。如果有人可以帮助我使我的想法走上正轨,我将不胜感激。

谢谢!

4

2 回答 2

3

编辑我在这里发布了一个示例 Rails 应用程序,展示了我在回答中所说的内容。我还发布了一个新的提交,其中包含演示如何处理俯卧撑提醒的评论,当它们以非嵌套方式可用时。

毫无疑问,保罗走在正确的轨道上。您需要在两个地方创建此功能,如果您想将其作为 cron 作业运行,第二个很重要。

  1. 在您的PushupRemindersController, 作为User;的嵌套资源 为了通过网络创建俯卧撑提醒。
  2. 在 rake 任务中,它将作为 cron 作业运行。

Rails 已经为您提供了您需要的大部分代码,并且您已经在 ActiveRecord 关联中设置了大部分代码。对于 #1, in routes.rb,设置嵌套路由...

# Creates routes like...
#   /users/<user_id>/pushup_reminders
#   /users/<user_id>/pushup_reminders/new
#   /users/<user_id>/pushup_reminders/<id>
resources :users do
  resources :pushup_reminders
end

PushupRemindersController应该看起来像......

class PushupRemindersController < ApplicationController
  before_filter :get_user

  # Most of this you'll already have.

  def index
    @pushup_reminders = @user.pushup_reminders
    respond_with @pushup_reminders
  end

  # This is the important one.
  def create
    attrs = {
      :completed => false,
      :num_pushups => @user.pushups_per_reminder,
      :when_sent => Time.now
    }
    @pushup_reminder = @user.pushup_reminders.create(attrs)
    respond_with @pushup_reminder
  end

  # This will handle getting the user from the params, thanks to the `before_filter`.
  def get_user
    @user = User.find(params[:user_id])
  end
end

当然,您将有一个new动作来向用户展示一个网络表单,等等。

对于第二个用例,cron任务,将其设置为项目目录中的Rake 任务。lib/tasks这使您可以自由支配设置一个在您需要时通过 cron 任务执行的操作。您将拥有对所有 Rails 模型等的完全访问权限,就像控制器操作一样。真正的诀窍是:如果您有疯狂的自定义逻辑来设置提醒,请将其移至PushupReminder模型中的操作。这样,您可以从 rake 任务和控制器中触发创建方法,而不必重复编写任何创建逻辑。记住,不要重复自己(干)!

我发现在设置cron任务时非常有用的一个 gem 是when gem。用 Ruby 编写特定于站点的 cron 作业,并获得您需要粘贴到 cron 选项卡中的确切输出(如果您通过 Capistrano 进行部署,则对 cron 作业进行完全不干涉管理)!

于 2012-11-24T04:19:55.313 回答
1

尝试将 attr_accessible 设置为 :user 而不是 :user_id。

attr_accessible :user

然而,一个更好的方法是这样做

@user.pushup_reminders.create

这样 user_id 会自动分配。

使用这样的嵌套路由:

:resources :users do
  :resources :pushup_reminders
end

这将为您提供 params[:user_id] 和 params[:id] 以便您可以在数据库中找到您的对象。

如果您通过会话了解您的用户,则无需嵌套您的路线,而是可以使用它来保存内容。

使用 restful 路由,我建议使用 pushup_reminders 控制器中的 create 操作。这将是进行这种对象创建的最传统和最安静的方式。

def create
  @user = User.find(params[:user_id]
  @reminder  = @user.pushup_reminders.create()
end

如果您需要检查对象创建是否成功,请尝试使用.newand.save

于 2012-11-24T00:16:39.230 回答