Rails Unpermitted参数使用嵌套表单和paperclip gem

时间:2015-10-22 23:37:57

标签: ruby-on-rails ruby paperclip nested-forms params

我正在创建一个网站,用户可以在该网站上发布可以包含许多照片的广告。

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

这是我认为问题所在的主程序。 我已从此代码中测试了许多不同的版本,但没有一个版本成功。

控制台中的params散列返回正确的值,它只是操纵它会导致问题。

  

{ “UTF8”=> “中✓”,   “authenticity_token”=> “中3OWguFpgwOYaLmQ4szRmPK / i13kLRr4XT1hcU6YEVlgml1iK1OzAg5c9UyETK1MiqdpoHYLcDGgx4aGd / FaZJg ==”,

     

“property”=> {“title”=>“asda”,“price”=>“3”,“numberOfBeds”=>“4”,   “厕所”=>“34”,“描述”=>“沙拉”,   “照片”=> { “property_pic”=>#,   @ original_filename =“ASC_0321.jpg”,@ content_type =“image / jpeg”,   @ headers =“Content-Disposition:form-data;   名= \ “属性[照片] [property_pic] \”;   filename = \“ASC_0321.jpg \”\ r \ nConContent-Type:image / jpeg \ r \ n“>}},   “commit”=>“创建广告”}

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

属性/ 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>

谢谢!

2 个答案:

答案 0 :(得分:2)

我几天前在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

答案 1 :(得分:2)

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

始终,始终始终snake_case名称呼叫filesattributes。按其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>是在CSS中执行此操作的正确方法时,人们使用margin-topmargin-bottom在其应用程序中创建空格。