airrecord
airrecord copied to clipboard
Problem with client association on create
I was unable to create a record in my Sale
model. Then I found that it's because I have a relationship named client
and I think it's collisioning with Airrecord::Table.client.
This is the problem:
class Sale < Airrecord::Table
self.base_key = ENV['AIRTABLE_BASE_ID']
self.table_name = 'Venta'
belongs_to :client, class: "Client", column: "Cliente"
end
Sale.create('Notas' =>'hola')
NoMethodError: undefined method `connection' for nil:NilClass
from /Users/juanjo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/airrecord-1.0.7/lib/airrecord/table.rb:153:in `create'
But it works if I comment the relationship:
class Sale < Airrecord::Table
self.base_key = ENV['AIRTABLE_BASE_ID']
self.table_name = 'Venta'
# belongs_to :client, class: "Client", column: "Cliente"
end
Sale.create('Notas' =>'hola')
=> #<Sale:0x00007f8e4d5069b8
@created_at=2021-08-12 02:30:29 UTC,
@fields={"ID"=>183, "Notas"=>"hola", "Creado en"=>"2021-08-12T02:30:29.000Z", "Subtotal"=>0, "Total"=>0, "Total despues comisiones"=>0, "Total Efectivo"=>0, "Total Bancos"=>0},
@id="rec3psj5RFUhd5Zhg",
@updated_keys=[]>
Is this the actual error? What are the alternatives for a fix? (I work on a solution with guidance, would be my first time) Can we document client
is reserved?
yes, your belongs_to
is clashing with Airrecord client
class method. Probably it would be better to raise a warning message or an exception when defining the belongs_to
method here, if an Airrecord method is being overriden:
def has_many(method_name, options)
safely_define_method(method_name.to_sym) do
# Get association ids in reverse order, because Airtable's UI and API
# sort associations in opposite directions. We want to match the UI.
ids = (self[options.fetch(:column)] || []).reverse
table = Kernel.const_get(options.fetch(:class))
return table.find_many(ids) unless options[:single]
(id = ids.first) ? table.find(id) : nil
end
safely_define_method("#{method_name}=".to_sym) do |value|
self[options.fetch(:column)] = Array(value).map(&:id).reverse
end
end
def safely_define_method(method_name, &block)
# Warn if method exists
if method_defined?(method_name)
warn "#{self.name}: overriding method '#{method_name}'!"
end
end
send(:define_method, method_name, &block)
end
Note I haven't tested this implementation. What do you think @sirupsen ?