Rails 在简单表单提交的模型属性中保存哈希
Rails Save Hash in Model Attribute Submitted by Simple Form
我正在构建一个 Rails5 应用程序,其中我有一个模型 Training
,属性 participant_ratings
,一个散列,它应该包含以 [=16] 的方式分配给培训的所有参与者的评分=].我已经设法构建了用于提交哈希的表单。
<%= 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
s 属性中。我收到错误:
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:
class Training < ApplicationRecord
...
serialize :participant_ratings, Hash
...
end
我必须更改什么才能将散列保存在我的 Training
模型的 participant_ratings
属性中?
你可以试试
@training.participant_ratings = params[:participant_ratings].to_hash
但我认为将其存储为 json 会更好,所以:
@training.participant_ratings = params[:participant_ratings].to_json
然后将其作为哈希读取:
hash = JSON.parse(@training.participant_ratings)
控制器出现错误。 update 方法没有得到 ratings 参数,所以它没有被保存。解决方法如下:
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
首先,(正如 Dmitry Kukhlevsky 所指出的),我必须确保 participants_rating
-hash 是 inside training
-hash当通过我的表单提交时,我不得不更改隐藏表单输入中的名称属性以获取评级:
<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
中找到了这个解决方案
之后participant_ratings
保存就好了!
仍然非常感谢 Dmitry 的所有帮助!!!
我正在构建一个 Rails5 应用程序,其中我有一个模型 Training
,属性 participant_ratings
,一个散列,它应该包含以 [=16] 的方式分配给培训的所有参与者的评分=].我已经设法构建了用于提交哈希的表单。
<%= 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
s 属性中。我收到错误:
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:
class Training < ApplicationRecord
...
serialize :participant_ratings, Hash
...
end
我必须更改什么才能将散列保存在我的 Training
模型的 participant_ratings
属性中?
你可以试试
@training.participant_ratings = params[:participant_ratings].to_hash
但我认为将其存储为 json 会更好,所以:
@training.participant_ratings = params[:participant_ratings].to_json
然后将其作为哈希读取:
hash = JSON.parse(@training.participant_ratings)
控制器出现错误。 update 方法没有得到 ratings 参数,所以它没有被保存。解决方法如下:
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
首先,(正如 Dmitry Kukhlevsky 所指出的),我必须确保 participants_rating
-hash 是 inside training
-hash当通过我的表单提交时,我不得不更改隐藏表单输入中的名称属性以获取评级:
<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
中找到了这个解决方案
之后participant_ratings
保存就好了!
仍然非常感谢 Dmitry 的所有帮助!!!