2015-01-20 4 views
1

У меня есть несколько моделей/контроллеры:Сильные параметры: Самовольная параметры: теги в 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 Unpermitted Parameters for Array. И я попытался добавить: tags: []. Но, похоже, это не работает в моем случае.


Debug информация: (в binding.pry точку останова вы видите выше)

[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>)> 
  • Как правильно разрешить :tags параметров?
  • Должен ли я обрабатывать представление тегов по-разному (например: метод event_params - правильное место для синтаксического разбора с разделом)?

ответ

2

От docs

Разрешено только скаляры через фильтр. ... передает параметры, ассоциированное значение которых имеет тип String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch :: Http :: UploadedFile или Rack :: Test :: UploadedFile. В противном случае ключ: имя отфильтровывается.

Вы не можете преобразовать элементы массива тегов в объекты AR, прежде чем разрешать атрибуты. Сначала вам нужно разрешить params, тогда вы можете мутировать его с объектами.

Обновлено: Глядя на railscasts вы можете увидеть, что модель, имеет метод: 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 
+0

Хорошо, я вижу. Где я должен делать мутацию? В контроллере (методы создания и обновления)? –

+0

@pinouchon Я обновил свой ответ. – Magnuss

1

Спасибо @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 
Смежные вопросы