Home > Software engineering >  ActiveModel::MissingAttributeError: can't write unknown attribute `property_id` with has_many a
ActiveModel::MissingAttributeError: can't write unknown attribute `property_id` with has_many a

Time:09-18

Schema was modified while I realized I was missing some IDs, but now I'm not sure what is missing. Using Rails 7.0.3.1.

create_table :properties do |t|
      t.string :code
      t.timestamp :create_date
      t.string :province
      t.string :county
      t.string :district
      t.string :area
      t.integer :rooms
      t.integer :bathrooms
      t.integer :parking
      t.boolean :pets
      t.text :address
      t.text :comments
      t.decimal :payment1
      t.decimal :payment2
      t.string :currency1
      t.string :currency2
      t.string :en_translation_key

      t.timestamps
    end
create_table :included_services do |t|
      t.references :property
      t.references :service

      t.timestamps
    end
create_table :included_amenities do |t|
      t.references :property
      t.references :amenity

      t.timestamps
    end

Models

class Property < ApplicationRecord
    belongs_to :property_type
    belongs_to :landlord
    has_one :property_transaction
    has_many_attached :photos
    has_many :included_amenities, dependent: :destroy
    has_many :included_services, dependent: :destroy
    has_many :amenities, through: :included_amenities
    has_many :services, through: :included_services
    validates_presence_of :code, :create_date, :province, :county, :district, :area, :pets, :address, :payment1, :currency1, :property_transaction
end
class IncludedAmenity < ApplicationRecord
    belongs_to :amenity
    belongs_to :property
end
class IncludedService < ApplicationRecord
    belongs_to :service
    belongs_to :property
end

Update: added controller creation code.

Controller

def create
    tmp_params = property_params
    @property = Property.new
    tmp_params[:landlord] = Landlord.find(tmp_params[:landlord])
    tmp_params[:property_type] = PropertyType.find(tmp_params[:property_type])
    tmp_params[:property_transaction] = PropertyTransaction.find(tmp_params[:property_transaction])
    tmp_params[:services] = tmp_params[:services].reject { |service| service == '' }.map { |service| Service.find(service) }
    tmp_params[:amenities] = tmp_params[:amenities].reject { |amenity| amenity == '' }.map { |amenity| Amenity.find(amenity) }
    province_name = search_province_name(tmp_params[:province])[tmp_params[:province]]
    county_name = search_county_name(tmp_params[:province], tmp_params[:county])[tmp_params[:county]]
    tmp_params[:district] = search_district_name(tmp_params[:province], tmp_params[:county], tmp_params[:district])[tmp_params[:district]]
    tmp_params[:province] = province_name
    tmp_params[:county] = county_name
    @property.attributes = tmp_params

    respond_to do |format|
      if @property.save
        format.html { redirect_to @property, notice: "Property was created successfully." }
        format.json { render :show, status: :created, location: @property }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @property.errors, status: :unprocessable_entity }
      end
    end
  end

def property_params
      params.require(:property).permit(:code, :create_date, :property_transaction, :province, :county, :district, :area, :rooms,
        :bathrooms, :parking, :payment1, :payment2, :currency1, :currency2,
        :pets, :landlord, :address, :comments, :property_type, services: [], amenities: [], photos: [])
    end

Error when trying to create a complete Property is:

ActiveModel::MissingAttributeError (can't write unknown attribute `property_id`

          raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
          ^^^^^):

Can't think of any other place where it could try to be looking for a property_id attribute.

CodePudding user response:

After cleaning up the controller code and assigning every attribute one by one, I saw that the culprit seemed to be this line:

@property.property_transaction = PropertyTransaction.find(property_params[:property_transaction])

So I took a look at the relationship one more time and it was obvious:

class Property < ApplicationRecord
    belongs_to :property_type
    belongs_to :landlord
    has_one :property_transaction
class PropertyTransaction < ApplicationRecord
    has_many :properties
    validates_presence_of :name, :en_translation_key
    validates_uniqueness_of :name, :en_translation_key
end

There was no child relationship, so the fix is simply this:

class Property < ApplicationRecord
    belongs_to :property_type
    belongs_to :landlord
    belongs_to :property_transaction

Migrations were correct actually, so this was all I needed.

  • Related