修改ruby hash到位(rails strong params)

Dre*_*w H 45 ruby ruby-on-rails-4

这可能是一个红宝石问题然后rails问题,但我很确定我能够在vanilla ruby​​应用程序中执行此操作.

我有强大的params定义.

def trip_params
  params.require(:trip).permit(:name, :date)
end
Run Code Online (Sandbox Code Playgroud)

现在我在控制器方法中得到了这些参数.我想做这个.

def save
  trip_params[:name] = 'Modifying name in place'
  #trip_params[:name] still equals original value passed
end
Run Code Online (Sandbox Code Playgroud)

这永远不会奏效. 名称不会改变.BTW:trip_params的类型是ActionController :: Parameters

如果我做一个标准的ruby脚本,它可以工作.

test = {}    
test[:name] = "blah"    
test[:name] = "ok"    
puts test #{:name=>"ok"}
Run Code Online (Sandbox Code Playgroud)

Nic*_*eys 58

permit返回带有这些键的新哈希,因此您不会修改实params变量.你也没有保存对hash_params返回值的引用,所以你每次调用都会得到它save.

试试这个:

def save
  tp = trip_params
  tp[:name] = 'Modifying name in place'
  # ... use tp later, it'll be in there
end
Run Code Online (Sandbox Code Playgroud)

或者,如果您真的希望以前所述的方式使用它,请按以下方式进行修改trip_params:

def trip_params
  @trip_params ||= params.require(:trip).permit(:name, :date)
end
Run Code Online (Sandbox Code Playgroud)

现在,哈希被缓慢地缓存,并且在后续trip_params调用中返回相同的哈希值.


Ива*_*вац 24

如果你真的想在控制器中更改params,你可以这样做:

def save
  params[:trip][:name] = 'Modifying name in place'
  # Now trip_params[:name] is 'Modifying name in place'
end
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最好最简单的答案.只需先修改实际参数,然后调用强参数方法.你甚至可以使用before_action:modify_params,只有[:create,:update]来创建一个私有方法,使其远离你的创建和更新方法. (9认同)

Cru*_*nez 5

你也可以

def save
  data = trip_params.merge(name: 'new name')
  # use data later
end
Run Code Online (Sandbox Code Playgroud)

如果新的散列合并到旧的散列中,并且有重复的键,则新的散列的键会覆盖旧的散列的匹配键。