diff --git a/app/controllers/rsvps_controller.rb b/app/controllers/rsvps_controller.rb index a8d0987..acf8251 100644 --- a/app/controllers/rsvps_controller.rb +++ b/app/controllers/rsvps_controller.rb @@ -1,6 +1,9 @@ class RsvpsController < ApplicationController def create @rsvp = Rsvp.find_or_create_by_email!(rsvp_params[:email]) + if @rsvp.airtable_record_id.blank? + @rsvp.update!(url_params: rsvp_params[:url_params]) + end flash[:success] = "Thanks for your interest! We'll be in touch soon." redirect_to root_path rescue ActiveRecord::RecordInvalid @@ -11,6 +14,6 @@ class RsvpsController < ApplicationController private def rsvp_params - params.permit(:email) + params.permit(:email, :url_params) end end diff --git a/app/jobs/sync_rsvp_with_airtable_job.rb b/app/jobs/sync_rsvp_with_airtable_job.rb new file mode 100644 index 0000000..a13968b --- /dev/null +++ b/app/jobs/sync_rsvp_with_airtable_job.rb @@ -0,0 +1,8 @@ +class SyncRsvpWithAirtableJob < ApplicationJob + queue_as :default + + def perform(rsvp_id) + rsvp = Rsvp.find(rsvp_id) + rsvp.sync_with_airtable! + end +end diff --git a/app/models/rsvp.rb b/app/models/rsvp.rb index ba335b0..a3114d1 100644 --- a/app/models/rsvp.rb +++ b/app/models/rsvp.rb @@ -1,7 +1,45 @@ class Rsvp < ApplicationRecord validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP } + after_create :enqueue_airtable_sync + def self.find_or_create_by_email!(email) find_or_create_by!(email: email.downcase.strip) end + + def sync_with_airtable! + uri = URI("https://api.airtable.com/v0/appuDQSHCdCHyOrxw/tblhGTc3WX9nYzU18") + + request = Net::HTTP::Patch.new(uri) + request["Authorization"] = "Bearer #{ENV.fetch("AIRTABLE_API_KEY")}" + request["Content-Type"] = "application/json" + request.body = { + performUpsert: { + fieldsToMergeOn: [ "email" ] + }, + records: [ + { + fields: { + email: email, + url_params: url_params + } + } + ] + }.to_json + + response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| + http.request(request) + end + + puts response.body + + self.airtable_record_id = JSON.parse(response.body).dig("records", 0, "id") + save! + end + + private + + def enqueue_airtable_sync + SyncRsvpWithAirtableJob.perform_later(id) + end end diff --git a/app/views/landing/index.html.erb b/app/views/landing/index.html.erb index bfa6413..a0c74ef 100644 --- a/app/views/landing/index.html.erb +++ b/app/views/landing/index.html.erb @@ -22,6 +22,7 @@ <%= form_with url: rsvp_path, method: :post, local: true do |form| %>
<%= form.text_field :email, placeholder: "Enter your email", class: "landing-input bg-white text-black px-4 py-2 flex-grow" %> + <%= form.hidden_field :url_params, value: request.query_string %> <%= form.submit "→", class: "landing-button bg-[#544FFF] text-white px-4 py-2 font-bold" %>
<% end %> diff --git a/db/migrate/20250508184653_add_airtable_record_id_to_rsvps.rb b/db/migrate/20250508184653_add_airtable_record_id_to_rsvps.rb new file mode 100644 index 0000000..b18395a --- /dev/null +++ b/db/migrate/20250508184653_add_airtable_record_id_to_rsvps.rb @@ -0,0 +1,5 @@ +class AddAirtableRecordIdToRsvps < ActiveRecord::Migration[8.0] + def change + add_column :rsvps, :airtable_record_id, :string + end +end diff --git a/db/migrate/20250508185907_add_url_params_to_rsvps.rb b/db/migrate/20250508185907_add_url_params_to_rsvps.rb new file mode 100644 index 0000000..11f157f --- /dev/null +++ b/db/migrate/20250508185907_add_url_params_to_rsvps.rb @@ -0,0 +1,5 @@ +class AddUrlParamsToRsvps < ActiveRecord::Migration[8.0] + def change + add_column :rsvps, :url_params, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 37901a3..74e9111 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,10 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_05_08_025519) do +ActiveRecord::Schema[8.0].define(version: 2025_05_08_185907) do + # These are extensions that must be enabled in order to support this database + enable_extension "pg_catalog.plpgsql" + create_table "action_text_rich_texts", force: :cascade do |t| t.string "name", null: false t.text "body" @@ -53,6 +56,8 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_08_025519) do t.string "email" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "airtable_record_id" + t.string "url_params" t.index ["email"], name: "index_rsvps_on_email", unique: true end