2017-10-10 38 views
1

我有三种模式,服务器有很多维护,维护属于服务器和用户。Rails强大的参数 - 用外键参数创建动作

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") 

我的问题是:如何才能在我控制器做这个动作创造? 问题是,:user_id不是维护PARAMS哈希的一部分,所以如果我写

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 => 
+0

语法错误是因为在ruby中的方法调用中的序号参数之前不能有散列键。 'permit(:id,:name,:content,:user_id => current_user.id)'在语法上是有效的 - 但是你应该使用一个块来代替将它们合并到传入参数中。 – max

回答

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 
3

您可以添加,USER_ID您创建行动本身里面。尝试这个。

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

记录正在保存,但user_id为空。 (我没有嵌套参数或类似于我的模型中写的东西) –

2

一个好方法是通过使一个块至create!方法:

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

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

这也适用于new,create,updateupdate!

但是,您应该考虑是否应该在此处使用爆炸方法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的::持久性爆炸方法应该只有真正喜欢的东西种子文件,或者未通过验证的记录是一个特殊的事件中使用。