Strong parameters: Unpermitted parameters: tags in has_many_through relation

十年热恋 提交于 2019-12-23 02:59:05

问题


I have a few models/controllers:

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)

My problem is that when I submit the form to create an event, I get:

Unpermitted parameters: tags

Yes, I've seen this post: Rails 4 Unpermitted Parameters for Array. And I've tried adding: tags: []. But it doesn't seem to work in my case.


Debug info: (at the binding.pry breakpoint you see above)

[4] pry(#<EventsController>)> params
=> {"utf8"=>"✓",
 "authenticity_token"=>"634lFWEsVDCD+yqPKBigmEJB0kRdHlLmyJpRwjTTVhU=",
 "event"=>
  {"name"=>"test tag 17",
   "category_id"=>"1",
   "date"=>" ",
   "tags"=>
    [#<Tag id: 3, name: "beer", created_at: "2014-12-05 11:21:27", updated_at: "2014-12-05 11:21:27">,
     #<Tag id: 4, name: "vodka", created_at: "2014-12-05 11:21:27", updated_at: "2014-12-05 11:21:27">,
     #<Tag id: 5, name: "champain", created_at: "2014-12-05 11:21:27", updated_at: "2014-12-05 11:21:27">],
   "skills"=>[],
   "spots"=>"",
   "description"=>"sdfsf"},
 "action"=>"create",
 "controller"=>"events"}
[5] pry(#<EventsController>)> event_params
Unpermitted parameters: tags
=> {"name"=>"test tag 17", "date"=>" ", "description"=>"sdfsf", "category_id"=>"1", "skills"=>[], "spots"=>""}
[6] pry(#<EventsController>)>
  • How do I properly permit the :tags param ?
  • Should I handle the submission of the tags differently (eg: is the event_params method the right place to do the parsing with split) ?

回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/28049879/strong-parameters-unpermitted-parameters-tags-in-has-many-through-relation

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