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.