Rails强参数 - 使用外键参数创建操作

时间:2017-10-10 09:11:15

标签: ruby-on-rails ruby-on-rails-5

我有三种型号,Server有很多维护,维护属于Server和User。

create_table :maintenances do |t|
  t.references :server, foreign_key: true
  t.references :user, foreign_key: true
  t.string :name
  t.text :content
end

在控制台中,我可以按如下方式创建记录:

Server.create(:hostname => "Sissy", :description => "Webserver")
Maintenance.create(:server_id => 1, :user_id => 1, :name => "Test", :content => "Test" )

我的问题是:如何在我的Controller创建操作中执行此操作? 问题是:user_id不是维护参数哈希的一部分,所以如果我写

def create
  @server = Server.find(params[:id])
  @maintenance = @server.maintenances.create!(maintenance_params)
end

  private
    def maintenance_params
      params.require(:maintenance).permit(:user_id => current_user.id, 
                                          :id, 
                                          :name, 
                                          :content)    
    end

我正在

Syntax error, unexpected ',', expecting =>
...ser_id => current_user.id, :id, :name, :content, :start, :pl...
...                               ^):

app/controllers/maintenances_controller.rb:41: syntax error, unexpected ',', expecting =>

3 个答案:

答案 0 :(得分:3)

您可以在create action中添加user_id。试试这个。

def create
  @server = Server.find(params[:id])
  params[:maintenance][:user_id] = current_user.id
  @maintenance = @server.maintenances.create!(maintenance_params)
end

答案 1 :(得分:2)

一个好方法是将块传递给create!方法:

@maintenance = @server.maintenances.create!(maintenance_params) do |m|
  m.user = current_user
end

记录产生于块(在验证/保存之前)。

这也适用于newcreateupdateupdate!

但是你应该考虑是否应该在这里使用爆炸方法create!,因为如果任何验证失败,它将引发未被捕获的ActiveRecord::RecordNotValid错误。

def create
  @server = Server.find(params[:id])
  @maintenance = @server.maintenances.new(maintenance_params) do |m|
    m.user = current_user
  end
  if @maintenance.save
    redirect_to @maintenance
  else
    render :new 
  end
end

ActiveRecord :: Persistence bang方法应该只用于种子文件之类的内容,或者不通过验证的记录是异常事件的地方。

答案 2 :(得分:0)

是的,你不能在strong_params方法中做任何类似的事情。它也不是它的目的。将白名单和默认参数分开。

我通常这样做:

def create
  @server      = Server.find(params[:id])
  @maintenance = @server.maintenances.create!(maintenance_params.merge(user_id: current_user.id))
end

private
def maintenance_params
  params.require(:maintenance).permit(:id, :name, :content)
end