Rails在简单表单提交的模型属性中保存哈希值

时间:2017-01-28 17:32:46

标签: ruby-on-rails hash simple-form strong-parameters

我正在构建一个Rails5应用,其中我有一个带有country属性的模型int main(){ int sum_digits(int tiv) { int sum = 0; while (tiv > 0) { sum += tiv % 10; tiv /= 10; }; return sum; }; int num_root(int num) { int root = sum_digit(int num); while(root > 9) { sum_digits(int root); }; return root; }; return 0; } ,这个哈希应该按照Training的方式保存分配给培训的所有参与者的评级。我已经设法构建了提交哈希的表单。

participant_ratings

我可以看到哈希被正确发送到服务器:
participant.id => rating value

但我无法管理此哈希值以保存在<%= simple_form_for @training do |f| %> ... <div id="ratings-container" style="display: inline-block; vertical-align: top"> <%= f.label t('trainings._form.ratings') %> <% Participant.all.order(:name).each do |p| %> <span class="checkbox_container"> <% current_rating = @training.participant_ratings[p.id].nil? ? '' : @training.participant_ratings[p.id] %> <label id='star<%= "#{p.id}" %>' data-rating='<%= "#{current_rating}" %>' style="margin-bottom: 12px;" ></label> <input id="rating<%= "#{p.id}" %>" name="participant_ratings[<%= "#{p.id}" %>]" type="hidden" value="<%= "#{@training.participant_ratings[p.id]}" %>" /> </span> <script> $('#star<%= "#{p.id}" %>').raty({ score: function() { return $(this).attr('data-rating'); }, half : true, readOnly: <%= !@training.participants.include?(p) %>, path: '/assets', click : function(score, evt) { $('#rating<%= "#{p.id}" %>').val(score); } }); $('#training_participant_ids_<%= "#{p.id}" %>').change(function () { var star = $('#star<%= "#{p.id}" %>'); if(document.getElementById('training_participant_ids_<%= "#{p.id}" %>').checked) { star.raty('readOnly', false); } else { star.raty('cancel'); star.raty('readOnly', true); $('#rating<%= "#{p.id}" %>').val(""); } }) </script> <% end %> </div> ... <% end %> 属性中。我收到错误: "participant_ratings"=>{"3"=>"5", "1"=>"3.5", "2"=>""}

我的控制器代码:

Training

我的Attribute was supposed to be a Hash, but was a ActionController::Parameters. -- <ActionController::Parameters {"3"=>"5", "1"=>"3.5", "2"=>""} permitted: false>课程:

class TrainingsController < BaseController
...
  def update
    @training = Training.find(params[:id])
    @training.updated_date_time = DateTime.now
    @training.participant_ratings = params[:participant_ratings]

    if @training.update(training_params)
      flash[:notice] = t('flash.training.updated')
      redirect_to @training
    else
      render 'edit'
    end
  end

  private
    def training_params
      params.require(:training).permit(:village, :topic, :user_id, :start_time, :end_time, {:participant_ids => []}, :participant_ratings)
    end
end

我必须更改哪些内容才能将哈希保存在Training模型的class Training < ApplicationRecord ... serialize :participant_ratings, Hash ... end 属性中?

3 个答案:

答案 0 :(得分:0)

你可以尝试

@training.participant_ratings = params[:participant_ratings].to_hash

但我认为将它存储为json会更好,所以:

@training.participant_ratings = params[:participant_ratings].to_json

然后把它读作哈希:

hash = JSON.parse(@training.participant_ratings)

答案 1 :(得分:0)

控制器出错。更新方法没有获得评级参数,因此它未保存。这是解决方法:

class TrainingsController < BaseController
...
  def update
    @training = Training.find(params[:id])
    @training.updated_date_time = DateTime.now
    @training.participant_ratings = params[:participant_ratings]
    @training.assign_attributes(training_params)

    if @training.save
      flash[:notice] = t('flash.training.updated')
      redirect_to @training
    else
      render 'edit'
    end
  end

  private
    def training_params
      params.require(:training).permit(:village, :topic, :user_id, :start_time, :end_time, {:participant_ids => []})
    end
end

答案 2 :(得分:0)

首先,(正如Dmitry Kukhlevsky所指出的那样),我必须确保participants_rating - 哈希是里面的 training - 哈希,当我的表单提交时,所以我必须更改我的隐藏表单输入中的名称属性为评级:

<input id="rating<%= "#{p.id}" %>" name="training[participant_ratings][<%= "#{p.id}" %>]" type="hidden" value="<%= "#{@training.participant_ratings[p.id]}" %>" />

其次,我必须将participant_ratings - 哈希的密钥列入白名单,以便允许它们:

def training_params
  ratings_keys = params[:training].try(:fetch, :participant_ratings, {}).keys
  params.require(:training).permit(:village, :topic, :user_id, :start_time, :end_time, {:participant_ids => []}, participant_ratings: ratings_keys )
end

我在this rails thread

中找到了这个解决方案

之后participant_ratings保存得很好!

仍然非常感谢德米特里的所有帮助!