Rails 使用嵌套表单和回形针的不允许参数 gem

Rails Unpermitted parameter using nested forms and paperclip gem

我正在创建一个网站,用户可以在其中 post 一个 属性 的广告,其中可以有很多照片。

我已经解决这个问题 2 天了,none 我找到的答案对这个问题有效。

我认为这是问题所在的主程序。 我已经根据此代码测试了许多不同的版本并且 none 已经成功。

控制台中的参数散列 returns 正确值,只是对它的操作导致了问题。

{"utf8"=>"✓", "authenticity_token"=>"3OWguFpgwOYaLmQ4szRmPK/i13kLRr4XT1hcU6YEVlgml1iK1OzAg5c9UyETK1MiqdpoHYLcDGgx4aGd/FaZJg==",

"property"=>{ "title"=>"asda", "price"=>"3", "numberOfBeds"=>"4", "toilets"=>"34", "description"=>"salads", "photo"=>{"property_pic"=>#, @original_filename="ASC_0321.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"property[photo][property_pic]\"; filename=\"ASC_0321.jpg\"\r\nContent-Type: image/jpeg\r\n">}}, "commit"=>"Create Ad"}

property.rb

    class Property < ActiveRecord::Base
      belongs_to :user
      has_many :photos  , dependent: :destroy
      accepts_nested_attributes_for :photos , reject_if: lambda  {|t| t['photo'].nil? 
}
    end

properties_controller.rb

  def new
    @property = Property.new
    @photo  = @property.photos.new
  end

  def create

     @property  = current_user.properties.new(params[:property])

     @property.photos.new(params[[:photo][:property_pic]])
    if @property.save
      redirect_to property_path @property
    else
      render :edit
    end

  end

 def property_params
    params.require(:property).permit(:title,:price,:numberOfBeds,:toilets,:description , photo:[:property_pic])
  end

properties/new.html.erb

<div class="wrapper_skinny">

  <%= form_for @property do |p| %>

      <%= p.label :title %>
      <%= p.text_field :title %> <br><br>

      <%= p.label :price %>
      <%= p.number_field :price %> <br><br>

      <%= p.label :numberOfBeds %>
      <%= p.number_field :numberOfBeds %> <br><br>

      <%= p.label :toilets %>
      <%= p.number_field :toilets %> <br><br>

      <%= p.label :description %>
      <%= p.text_area :description %> <br><br>

      <%= p.fields_for :photo  do |builder|  %>
          <%= builder.label :property_pic %>
          <%= builder.file_field :property_pic %>
      <% end %> <br><br>


      <%= p.submit "Create Ad" , class:"button button-chosen"%>
  <% end %>

</div>

谢谢!

几天前我在 rails 4.

中尝试过

您必须将 new 方法更改为此方法才能在照片对象中添加 property_id

def new
  @property = Property.new
  @property.photos.new
end

然后,在您的 create 方法中。我想,您不需要手动将照片渲染为 new 方法。

def create
  @property  = current_user.properties.new(property_params)
  if @property.save
    redirect_to property_path @property
  else
    render :new
  end
end

接下来,您必须将 field_for 表格编辑为

<%= p.fields_for :photos  do |builder|  %>
  <%= builder.label :property_pic %>
  <%= builder.file_field :property_pic %>
<% end %>

最后把你的强参数改成

def property_params
  params.require(:property).permit(:title,:price,:numberOfBeds,:toilets,:description, photos_attributes: [:id, :property_pic])
end

希望对您有所帮助。这是 rails 4 nested form

的制作方法

根据 Muhamad 的回答,这是我要做的(几处更改):

#app/models/property.rb
class Property < ActiveRecord::Base
   belongs_to :user
   has_many :photos
   accepts_nested_attributes_for :photos, reject_if: :all_blank #-> seems like you're doing this incorrectly
end

#app/controllers/properties_controller.rb
class PropertiesController < ApplicationController
   def new
      @property = current_user.properties.new
      @property.photos.build
   end

   def create
      @property = current_user.properties.new property_params
      @property.save
   end

   private

   def property_params
       params.require(:property).permit(:title,:price,:number_of_beds,:toilets,:description , photos_attributes: [:property_pic])
   end
end

这应该可以解决您的问题(您的参数显示您正在传递嵌套表单属性,但您需要确保使用 fields_for 帮助程序:

#app/views/properties/new.html.erb
<%= form_for @property do |f| %>
   <%= f.fields_for :photos do |photo| %>
       <%= photo.file_field :property_pic %>
   <% end %>
   <%= f.submit %>
<% end %>

备注

snake_case

总是,总是,总是filesattributes 用他们的 snake_case name. Call classes by their CamelCase 名字,其他一切按蛇形大小写。

-

HTML

你的HTML还可以大大提高:

#app/views/properties/new.html.erb
 <%= form_for @property do |p| %>

      <% options = [[:title, "text"], [:price, "number"], [:number_of_beds, "number"], [:toilets, "number"], [:description, "area"]] %>
 
      <% options.each do |type,input| %>
         <% input = "text_area" if input == "area" %>
         <%= p.label type %>
         <%= p.send(input, type)
      <% end %>

      <%= p.fields_for :photo  do |builder|  %>
          <%= builder.label :property_pic %>
          <%= builder.file_field :property_pic %>
      <% end %>

      <%= p.submit "Create Ad" , class:"button button-chosen"%>
  <% end %>

此外,不要使用 HTML 进行样式设置 - 仅使用 CSS.

人们使用 <p><br> 在他们的应用程序中创建空间,而 margin-top/margin-bottom 是在 [=54= 中创建空间的正确方法].