2

ネストされた属性を配列に分割して、一意性をチェックして保存できるようにする関数があります。問題は、削除する属性を強調表示するためにhidden_​​fieldが挿入されるCan't mass-assign protected attributes: _destroyため、エラーが発生することです。nested_form gem

*Posts_Contoller.rb*作成関数は次のとおりです。

def create
   location_set = params[:post].delete(:locations_attributes) unless params[:post][:locations_attributes].blank?

   @post = current_blogger.blog_posts.new(params[:post])

   @post.locations = Location.find_or_initialize_location_set(location_set) unless location_set.nil?


 if @post.save
    redirect_to @post, notice: 'Blog post was successfully created.'
  else
    render action: "new"
  end
end

location.rbの関数は次のとおりです。

def self.find_or_initialize_location_set(location_set)
  #create a locations array
   locations = []
         locations = locations.delete_if { |elem| elem.flatten.empty? }

   location_set.each do |key, location|
       locations << find_or_initialize_by_name(location)
   end

 locations

 end

そしてここにログがあります:

 Started POST "/blog/posts" for 127.0.0.1 at 2012-12-03 17:31:54 +0000
 Processing by Blogit::PostsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"r74iCzC4tJgVI6FiCEH7XzfiTmaqKihF5JSs7Ow3MSI=", "post"=>{"title"=>"This
 is a post about Paris", "body"=>"This is a post about ParisThis is a post about Paris
 This is a post about ParisThis is a post about Paris", "tag_list"=>"", 
 "locations_attributes"=>{"0"=>{"_destroy"=>"false", "name"=>"Paris", "longitude"=>"2.3522219", "latitude"=>"48.856614"}, "1354555760002"=>{"_destroy"=>"false", "name"=>"Los Angeles", "longitude"=>"-118.5155901", "latitude"=>"3
 4.03563310000001"}}}, "_wysihtml5_mode"=>"1", "name"=>"losds", "legname"=>"Los Angeles",    "longitude"=>"-118.5155901", "latitud
 e"=>"34.03563310000001", "commit"=>"Submit"}

 User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
 ActsAsTaggableOn::Tag Load (0.1ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON  "tags"."id" = "taggings"."tag_id" W
 HERE "taggings"."taggable_id" IS NULL AND "taggings"."taggable_type" = 'Blogit::Post' AND  (taggings.context = 'tags' AND taggings.tagger_id IS NULL)

 Location Load (0.1ms)  SELECT "locations".* FROM "locations" WHERE "locations"."name" = 'Paris' LIMIT 1
 LOGGER LOCATIONS ARE[#<Location id: 768, name: "Paris", latitude: #<BigDecimal:7f86aadf6230,'0.48856614E2',18(45)>, longitude:
 #<BigDecimal:7f86aadf5f60,'0.23522219E1',18(45)>, post_id: nil, created_at: "2012-12-01 17:27:33", updated_at: "2012-12-01 17
 :27:33", notes: nil>]
 Location Load (0.2ms)  SELECT "locations".* FROM "locations" WHERE "locations"."name" = 'Los Angeles' LIMIT 1
 Completed 500 Internal Server Error in 97ms

  ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: _destroy):
  app/models/location.rb:23:in `block in find_or_initialize_location_set'
  app/models/location.rb:21:in `each'
  app/models/location.rb:21:in `find_or_initialize_location_set'
  app/controllers/blogit/posts_controller.rb:79:in `create'

以前のようにパラメータに削除関数を含めるようにこれを適応させる方法についての提案はありますが、Can't mass-assign protected attributes: _destroyエラーは発生しませんか?

ありがとう!

4

2 に答える 2

3

これをロケーションモデルに追加することで、このエラーを取り除くことができます。

# NOT PERSISTENT
attr_accessor :_destroy
# ... 
attr_accessible :_destroy

これがないと、属性は一括割り当て_destroyから保護され、とにかく値を割り当てようとすると、例外がスローされます。

于 2012-12-03T17:54:08.233 に答える
0

あなたは次のようなことをすることができます:

def self.find_or_initialize_location_set(location_set)
  #create a locations array
  locations = []
  locations = locations.delete_if { |elem| elem.flatten.empty? }

  location_set.each do |key, location|
    if location.delete(:_destroy) == "1"
      locations.delete_if {|elem| elem[:name] == location[:name]}
    else
      locations << find_or_initialize_by_name(location)   
    end
  end 

  locations 
end

関連するハッシュを呼び出すdeleteと、ハッシュが変更され、削除する値が返されます(存在しnilない場合)。

または、初期化された場所で削除が必要な場合は、そこで行うことができます。

def find_or_initialize_by_name_with_delete(location)
  if location.delete(:_destroy)
    do_delete
  end

  find_or_initialize_by_name(location)
end
于 2012-12-03T18:33:25.300 に答える