0

A property has multiple pictures. The images uploaded in the form should be accessible through the Property class.

//Picture Model
class Picture < ApplicationRecord
  belongs_to :property
  has_attached_file :image, styles: { medium: "300x300>", thumb:"100x100>" }, default_url: "/images/:style/missing.png"
  validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
end

//Property Model
class Property < ApplicationRecord
  has_many :pictures, dependent: :destroy
  accepts_nested_attributes_for :pictures
end

//Form
<%= form_for @property, :html => {multipart: true} do |f| %>
  <%= f.fields_for :pictures do |ph| %>
    <%= ph.file_field :image, as: :file %>
  <% end%>
<% end%>

//Properties Controller
def new
  @property = Property.new
  @property.pictures.build
end

def create
  @property = current_user.properties.build(property_params)
  @property.seller = User.find(current_user.id) # links user to property via. user_id
  respond_to do |format|
    if @property.save
      format.html { redirect_to @property, notice: 'Property was successfully created.' }
      format.json { render action: 'show', status: :created, location: @property }
    else
      format.html { render action: 'new' }
      format.json { render json: @property.errors, status: :unprocessable_entity }
    end
  end
end

Error received when submitting form: Pictures property must exist

Supplicant
  • 13
  • 6

1 Answers1

0

In Rails 5, belongs_to automatically validates for presence. You can add optional: true to belongs_to:

class Picture < ApplicationRecord
  belongs_to :property, optional: true
end

Or you have to save Property before you create Picture:

EDIT: simple way to save property before create picture

# PropertyController
def create
  @property = current_user.properties.build(property_params)
  @property.seller = User.find(current_user.id) # links user to property via. user_id
  respond_to do |format|
    if @property.save
      @property.picture.create(picture_params)
      format.html { redirect_to @property, notice: 'Property was successfully created.' }
      format.json { render action: 'show', status: :created, location: @property }
    else
      format.html { render action: 'new' }
      format.json { render json: @property.errors, status: :unprocessable_entity }
    end
  end
end

def picture_params
    params.require(:property).permit(:picture)
end
Thiago Ururay
  • 482
  • 3
  • 15
  • Right, if I do that then they don't link. How would I save the Property before the picture? – Supplicant Jun 18 '17 at 10:19
  • See, when you use `belongs_to :property` in Picture it means that you will save property_id em picture, so property must be saved before! A simple way is: after `@property.save` you can do `@property.pictures.create(picture_params)` – Thiago Ururay Jun 18 '17 at 17:26