强参数:未允许的参数:has_many_through关系中的标记
我有几个型号/控制器:
event.rb:
class Event < ActiveRecord::Base belongs_to :category belongs_to :user has_many :event_tags has_many :tags, through: :event_tags has_many :event_skills has_many :skills, through: :event_skills
tag.rb
class Tag < ActiveRecord::Base has_many :events, through: :event_tags has_many :event_tags end
event_tag.rb
class EventTag < ActiveRecord::Base belongs_to :event belongs_to :tag end
user.rb:
class User < ActiveRecord::Base has_many :events # organized_events
events_controller.rb
class EventsController < ApplicationController ... def create @event = Event.new(event_params) @event.user_id = current_user.id respond_to do |format| if @event.save format.html { redirect_to @event, notice: 'L\'évènement a été crée.' } format.json { render json: @event, status: :created, location: @event } else format.html { render action: "new" } format.json { render json: @event.errors, status: :unprocessable_entity } end end end ... private def event_params params[:event][:date] = '%s %s' % [params[:event][:date].andand.split('/').reverse.join('-'), params[:event][:hour].andand.sub('h', ':')] params[:event].delete :hour params[:event][:tags] = params[:event][:tags].split(';').map { |t| Tag.where(name: t).first_or_create } params[:event][:skills] = params[:event][:skills].split(';').map { |s| Skill.where(name: s).first_or_create } binding.pry params.require(:event).permit(:user_id, :name, :date, :hour, :description, :picture, :category_id, {tags: []}, {skills: []}, :spots)
我的问题是,当我提交表单来创建一个事件时,我得到:
未允许的参数:标签
是的,我看过这篇文章: Rails 4数组的未经许可的参数 。 我尝试添加: tags: []
。 但它似乎不适用于我的情况。
调试信息:(在您看到的binding.pry断点处)
[4] pry(#)> params => {"utf8"=>"✓", "authenticity_token"=>"634lFWEsVDCD+yqPKBigmEJB0kRdHlLmyJpRwjTTVhU=", "event"=> {"name"=>"test tag 17", "category_id"=>"1", "date"=>" ", "tags"=> [#, #, #], "skills"=>[], "spots"=>"", "description"=>"sdfsf"}, "action"=>"create", "controller"=>"events"} [5] pry(#)> event_params Unpermitted parameters: tags => {"name"=>"test tag 17", "date"=>" ", "description"=>"sdfsf", "category_id"=>"1", "skills"=>[], "spots"=>""} [6] pry(#)>
- 我如何正确地允许
:tags
参数? - 我应该以不同的方式处理标记的提交(例如:event_params方法是使用split进行解析的正确位置)吗?
来自docs
只允许的标量通过filter。 …传递params,其关联值的类型为String,Symbol,NilClass,Numeric,TrueClass,FalseClass,Date,Time,DateTime,StringIO,IO,ActionDispatch :: Http :: UploadedFile或Rack :: Test :: UploadedFile。 否则,键:name被过滤掉。
在允许属性之前,不能将标记数组元素转换为AR对象。 你首先需要允许参数,然后你可以用对象改变它。
更新:看看railscast,你可以看到一个模型,有一个方法: tagged_with
你可以创建:
class Event < ActiveRecord::Base def tagged_with(*tag_names) # create (or build) your tags end end
在你的控制器中,你有event_params
, tag_params
和skill_params
def create @event = Event.new(event_params) @event.tagged_with(tag_params) # Same thing with skills @event.user_id = current_user.id ... end ... def tag_params params.require(:event).permit(tags: []) end
谢谢@Magnuss指出了这个问题。 (我不能允许AR类型的对象)。
我最终将控制器更改为:(现在它工作正常)
class EventsController < ApplicationController ... def create # added parse_event_params here. Also added in update method, not shown here. @event = Event.new(parse_event_params event_params) @event.user_id = current_user.id respond_to do |format| if @event.save format.html { redirect_to @event, notice: 'L\'évènement a été crée.' } format.json { render json: @event, status: :created, location: @event } else format.html { render action: "new" } format.json { render json: @event.errors, status: :unprocessable_entity } end end end private # added this method def parse_event_params(event_params) event_params[:date] = '%s %s' % [event_params[:date].andand.split('/').reverse.join('-'), event_params[:hour].andand.sub('h', ':')] event_params.delete :hour event_params[:tags] = event_params[:tags].split(';').map { |t| Tag.where(name: t).first_or_create } event_params[:skills] = event_params[:skills].split(';').map { |s| Skill.where(name: s).first_or_create } event_params end # changed this method so it's only doing require/permit def event_params params.require(:event).permit(:user_id, :name, :date, :hour, :description, :picture, :category_id, :tags, :skills, :spots) end