Strong parameters: Unpermitted parameters: tags in has_many_through relation

大憨熊 提交于 2019-12-08 03:47:30

From docs

Only permitted scalars pass the filter. ... passes params whose associated value is of type String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile or Rack::Test::UploadedFile. Otherwise, the key :name is filtered out.

You cannot convert tag array elements to AR objects before you permit the attributes. You first need to permit the params, then you can mutate it with objects.

Updated: Looking at railscasts you can see that a model, has a method: tagged_with

You could create:

class Event < ActiveRecord::Base
  def tagged_with(*tag_names)
    # create (or build) your tags
  end
end

In your controller, you'd have event_params, tag_params and 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

Thanks @Magnuss for pointing out the problem. (I cannot permit an object of AR type).

I ended up changing my controller to this: (And now it works fine)

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!