强参数:未允许的参数: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_paramstag_paramsskill_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