我有几个型号/控制器:
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: []
。但它似乎并不适用于我的情况。
调试信息:(在您看到的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
param?答案 0 :(得分:2)
来自docs
仅允许的标量通过过滤器。 ...传递params,其关联值的类型为String,Symbol,NilClass,Numeric,TrueClass,FalseClass,Date,Time,DateTime,StringIO,IO,ActionDispatch :: Http :: UploadedFile或Rack :: Test :: UploadedFile。否则,密钥:名称将被过滤掉。
在允许属性之前,无法将标记数组元素转换为AR对象。你首先需要允许参数,然后你可以用对象改变它。
<强>更新强>
查看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
答案 1 :(得分: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