Rails 5简单表单保存模型属性

时间:2017-01-23 21:23:59

标签: ruby-on-rails forms simple-form

在我的Rails 5应用程序中,我有一个简单表单表单,用于创建或更新我的模型Training。在此表单中,我已经为每个Participant提供了复选框,以将其分配给Training。现在,我尝试为每个Participant添加一个单选按钮组(5为1到5的等级),因为每个人都可以为Training评分。

Screen shot of the rendered form

我设法按照我想要的方式渲染单选按钮但不幸的是我只能选择所有渲染的单选按钮中的一个。它们甚至奇怪地与复选框相关联,这可能是因为它们具有相同的输入方法participant_ids,它与has_and_belongs_to_many Participant的{​​{1}}关联相连。 / p>

:participants

我尝试过很多东西,但我已经没有想法了。如果可能的话,我想填写<%= simple_form_for @training do |f| %> ... <div id="participants-ratings-container"> <div id="participants-container" style="display: inline-block; vertical-align: top; width: 8em"> <%= f.label t('activerecord.models.participant') %> <%= f.collection_check_boxes :participant_ids, Participant.all.order(:name), :id, :name, {:item_wrapper_class => 'checkbox-container'} %> </div> <div id="ratings-container" style="display: inline-block; vertical-align: top"> <%= f.label t('trainings._form.ratings') %> <% Participant.all.order(:name).each do |p| %> <%= f.input :participant_ids, collection: 1..5, as: :radio_buttons, label: false%> <% end %> </div> ... <% end %> 课程中的哈希participant_ratings的方式&#34; participant.name&#34; =&GT;评级值。

任何人都可以给我一个如何实现这一目标的提示吗?如果未检查相应的Training,甚至可以告诉我如何禁用单选按钮组?

提前致谢!

更新

我设法调整我的表单,甚至整合jQuery raty插件来输入每个Participant的评级值。每个评级与其对应的参与者ID一起作为散列发送到服务器,例如,散列。像这样:

Participant

如果未选中相应的参与者复选框,则会禁用每个评级,并将其值设置为0。这是我的观看代码:

"participant_ratings"=>{"3"=>"5", "1"=>"3.5", "2"=>""}.

New screen shot of the rendered form

我似乎无法弄清楚的最后一件事是如何在相应的模型属性<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> 中保存participant_ratings哈希

如果我在:participant_ratings中允许参数:participant_ratings,但没有保存。所以我添加了

trainings_controller.rb

现在我收到了错误

@training.participant_ratings = params[:participant_ratings]

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

trainings_controller.rb

如何将表单发送的哈希值保存在模型的属性中?我哪里出错了?
我能以某种方式将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 定义为类似于数组participant_ratings的参数中的散列吗?

1 个答案:

答案 0 :(得分:0)

首先,我必须确保在我的表单提交时,participant_rating-hash在training-hash中,因此我必须更改隐藏表单输入中的name属性以获得评级:

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

其次,我必须将参与者_ratings-hash的密钥列入白名单,以便允许这些密钥:

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

中找到了这个解决方案

之后,参与者保存得很好!