5

我陷入了一个不可能那么复杂的问题,但我只是没有把事情做好。

假设我有两个模型:

class Notification < ActiveRecord::Base
  belongs_to :device

  validates :number, presence: true
end

class Device < ActiveRecord::Base
  belongs_to :user
  has_many :notifications, :dependent => :destroy

  //rest omitted for brevity
end

嵌套路由如下:

 resources :devices do
   resources :notifications
 end

和这样的通知控制器:

class NotificationsController < ApplicationController
  before_filter :authenticate_user!
  before_action :set_device, :only => [:index, :new, :create]
  before_filter :load_notification, only: :create

  load_and_authorize_resource :device
  load_and_authorize_resource :notification, :through => :device


  def index
  end

  def new
    @notification = @device.notifications.build
  end

  def create
    params.each do |param|
      logger.debug param
    end
    @notification = @device.notifications.build(notification_params)
    if @notification.save
      redirect_to [@notification.device, @notifications], notice: 'Notification was successfully created.'
    else
      render action: 'new'
    end
  end

  private

  def load_notification
    @notification = Notification.new(notification_params)
  end

  def set_device
    @device = Device.find(params[:device_id])
  end

  def notification_params
    params.fetch(:notification, {}).permit(:number, :device_id, :message)
  end
end

现在,当涉及到创建通知时:表单按方面工作。但是:我想实现第二个目标。通知应该是可重新发送的,所以我在通知索引视图中有这个:

<%= link_to 'Resend', device_notifications_path(number: notification.number, message: notification.message), :method => :post %>

但是验证失败并且我重定向到新页面而没有任何预填充字段告诉我该数字是必需的,因此必须缺少一些我没有得到的明显内容。

请求中的参数:

[["user_id", xyz]]
["_method", "post"]
["authenticity_token", "myauthenticitytokenstring"]
["number", "+1555123456789"]
["action", "create"]
["controller", "notifications"]
["device_id", "9"]
["notification", {}]

(不需要留言)

我认为错误在于控制器中的 notification_params 方法。

任何人都可以帮助我吗?

4

1 回答 1

7

我刚才遇到了类似的问题,这对我有用:

<%= link_to 'Resend', device_notifications_path(@notification.device_id, notification: { number: notification.number, message: notification.message }), :method => :post %>

基本上,您需要将控制器/模型数据包装到控制器参数的散列中。这就是控制器本身读取它的方式。另外,你没有错过device_id你的device_notifications_path?

[["user_id", xyz]]
["_method", "post"]
["authenticity_token", "myauthenticitytokenstring"]    
["action", "create"]
["controller", "notifications"]
["device_id", "9"]
["notification", {["number", "+1555123456789"]}]

现在,这么说,我只是假设它device_id位于您的 URL 路由中: http:\\localhost:3000\notifications\9

这就是为什么device_id不必在哈希本身中。这只是基于我在这里的假设,没有更多的viewandroutes继续。总而言之,它确实与哈希有关。试一试,并使用p在你的 development.log 中打印数据进行测试:

def create
  p params
  p notification_params

  ...
end

此外,可选但不是必需的,您可以使用.require而不是.fetch像这样干掉控制器的参数 def:

private

def notification_params
  params.require(:notification).permit(:number, :device_id, :message)
end
于 2013-10-21T13:17:25.940 回答