【问题标题】:Rails - NoMethodError (undefined method 'permit' for "reps":string)Rails - NoMethodError(“reps”的未定义方法“permit”:字符串)
【发布时间】:2017-01-14 19:34:21
【问题描述】:

所以我试图从 Rails 5 中的单个表单创建多个对象。这在 Rails 4.2 中工作得非常好,我不确定是什么导致了错误(我想它与看法)。

升级到 rails 5 后我遇到的另一个问题是我的表单现在只提交最后一条记录。我将此演练用作参考:http://vicfriedman.github.io/blog/2015/07/18/create-multiple-objects-from-single-form-in-rails/

This is the input 和 这是我要发送的参数。

Parameters: {"utf8"=>"√", "authenticity_token"=>"3j8A0oNW3sM5VIi11ZEHwpwlAhvY3
vml1kcLHfWdptySKSeJokRmBXObh/HEFBwG4/QC8PdfX7NKbkrGjOfI6Q==", "exercise_id"=>"16
5", "exercise_sets"=>{"reps"=>"1", "weight"=>"1"}, "exerciseName"=>"imsick", "co
mmit"=>"Save changes"}

错误

NoMethodError (undefined method 'permit' for "reps":string)

ExerciseSetsController:

def create
    if current_trainer
        savedMirror = current_trainer.exercises.find_by_name(params[:exerciseName])

        params['exercise_sets'].each do |set|
            #set[:timeFormat] = savedMirror.exercise_sets[0].timeFormat
            #set[:weightFormat] = savedMirror.exercise_sets[0].weightFormat
            #set[:distanceFormat] = savedMirror.exercise_sets[0].distanceFormat
            ExerciseSet.create(exercise_set_params(set))
        end

        flash[:notice] = "Sets added"
        redirect_to (:back)
    end
end

private 
def exercise_set_params(e_params)
  e_params.permit(:id, :reps, :weight, :weightFormat, :time, :timeFormat, :distance, :distanceFormat, :exercise_id, :_destroy)
end

查看:

<%savedMirror = current_trainer.exercises.find_by_name(e.name)%>
<%= form_tag  url_for(controller: "exercise_sets", action: "create") do%>
    <ul class="list-group">
        <% e.sets.times do |i|%>
        <%= fields_for "exercise_sets[]", @exerciseSet do |f| %>
        <li class="list-group-item">
            <label>Set: <%=i+1%></label>
                <%#= f.number_field :user_id, value: e.user_id, style:"visibility:hidden; margin:-15px;"%>
                <%= hidden_field_tag(:exercise_id, e.id) %>

              <div class = "row">
                <% if savedMirror.exercise_sets[0].reps == 1%>
                  <div class="col-sm-3">
                    <%= f.label :reps, "Reps" %><br>
                    <%= f.text_field :reps, class: "form-control"%>
                  </div>
                <%end%>
                <% if savedMirror.exercise_sets[0].weight == 1%>
                  <div class="col-sm-3">
                    <%= f.label :weight, "Weight" %><br>
                      <%= f.text_field :weight, class: "form-control"%>
                  </div>
                <%end%>
                <% if savedMirror.exercise_sets[0].time == 1%>
                  <div class="col-sm-3">
                    <%= f.label :time, "Time" %><br>
                      <%= f.text_field :time, class: "form-control"%>
                  </div>
                <%end%>
                <% if savedMirror.exercise_sets[0].distance == 1%>
                  <div class="col-sm-3">
                    <%= f.label :distance, "Distance" %><br>
                    <%= f.text_field :distance, class: "form-control"%>
                  </div>
                <%end%>
              </div>
        </li>
        <%end%>
        <%end%>
        <br>
        <%= hidden_field_tag(:exerciseName, e.name) %>
        <%=submit_tag%>
    </ul>
    <% end %>
<%end%>

非常感谢任何帮助,谢谢!

【问题讨论】:

  • 您能否用您对 Rails 代码所做的更改来回答,并在一天后将其标记为回答?
  • 好点,已发布!

标签: html ruby-on-rails


【解决方案1】:

您需要添加.require(:exercise)(我假设您的模型名称是练习)才能使用强参数。

如果您不通过模型,要求将使您的应用程序出错。因为您列入白名单的参数是为该模型定义的。

只需替换

def exercise_set_params(e_params)
  e_params.permit(:id, :reps, :weight, :weightFormat, :time, :timeFormat, :distance, :distanceFormat, :exercise_id, :_destroy)
end

与

def exercise_set_params(e_params)
  e_params.require(:exercise).permit(:id, :reps, :weight, :weightFormat, :time, :timeFormat, :distance, :distanceFormat, :exercise_id, :_destroy)
end

希望它有效!

【讨论】:

  • 感谢您的帮助!不幸的是,我现在收到此错误:NoMethodError (private method 'require' called for "reps":string) 我相信这与我提交的参数格式有关。
【解决方案2】:

看起来像:reps、和:weight,像这样作为嵌套参数传递

"exercise_sets"=>{"reps"=>"1", "weight"=>"1"}

所以我很想试试这个:

e_params.permit(:id, exercise_sets: [:reps, :weight], :weightFormat, :time, :timeFormat, :distance, :distanceFormat, :exercise_id, :_destroy)

注意嵌套:

exercise_sets: [:reps, :weight]

也许这样就可以了。

【讨论】:

  • 您没有阅读代码。 params['exercise_sets'].each do |set| ... exercise_set_params(set) 所以e_params 已经是一个参数对象,应该只包含有问题的嵌套键。
  • 是的,我的错,看来这家伙解决了他的问题 :)
【解决方案3】:

修复问题:

我没有将值作为散列传递,而是将它们作为数组传递。我通过将各个字段更改为:

<input type="text" name="exercise_sets[][reps]" class="form-control" />

<input type="text" name="exercise_sets[][weight]" class="form-control" />

...等等。

【讨论】:

    【解决方案4】:

    在我的情况下,我在参数中使用 axios 为 ajax 发送数据时遇到了同样的问题,解决方案是在“数据”而不是“参数”中添加值

    axios({
            method:'patch',
            url:'/clients/'+ item +'/update.json',
            //params:{'client': {'info': info}},
            data:{authenticity_token:token,client:{info: info}},
            responseType:'json'
        })
    

    【讨论】:

      猜你喜欢
      • 2017-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多