rails 4带有link_to和带有强参数的方法帖子

Jul*_*fke 5 http-post link-to strong-parameters ruby-on-rails-4

我陷入了一个不会那么复杂的问题,但我只是没有把事情做对.

假设我有两个型号:

class Notification < ActiveRecord::Base
  belongs_to :device

  validates :number, presence: true
end
Run Code Online (Sandbox Code Playgroud)

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

  //rest omitted for brevity
end
Run Code Online (Sandbox Code Playgroud)

使用嵌套路线如下:

 resources :devices do
   resources :notifications
 end
Run Code Online (Sandbox Code Playgroud)

和这样的通知控制器:

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
Run Code Online (Sandbox Code Playgroud)

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

<%= link_to 'Resend', device_notifications_path(number: notification.number, message: notification.message), :method => :post %>
Run Code Online (Sandbox Code Playgroud)

但是验证失败并且重定向到新页面而没有任何预填充字段告诉我这个数字是必需的,所以必须遗漏一些我不明白的东西.

来自请求的参数:

[["user_id", xyz]]
["_method", "post"]
["authenticity_token", "myauthenticitytokenstring"]
["number", "+1555123456789"]
["action", "create"]
["controller", "notifications"]
["device_id", "9"]
["notification", {}]
Run Code Online (Sandbox Code Playgroud)

(不需要消息)

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

有人可以帮帮我吗?

Eri*_*hic 6

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

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

基本上,您需要将控制器/模型数据包装为控制器参数的哈希值.这就是控制器本身如何读取它.另外,你是不是错过了device_id你的device_notifications_path

[["user_id", xyz]]
["_method", "post"]
["authenticity_token", "myauthenticitytokenstring"]    
["action", "create"]
["controller", "notifications"]
["device_id", "9"]
["notification", {["number", "+1555123456789"]}]
Run Code Online (Sandbox Code Playgroud)

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

这就是为什么device_id不必在哈希本身.这只是基于我在这里假设没有更多的东西viewroutes继续.总而言之,它确实与哈希有关.玩一下,然后p用来打印你的development.log中的数据来测试:

def create
  p params
  p notification_params

  ...
end
Run Code Online (Sandbox Code Playgroud)

另外,可选但不是必需的,你可以使用.require而不是.fetch像这样干掉控制器的params def :

private

def notification_params
  params.require(:notification).permit(:number, :device_id, :message)
end
Run Code Online (Sandbox Code Playgroud)