Reputation: 738
I'm trying to save a Form Object in Rails through and association like this:
document.translations_forms.save(translation_params)
And on my Document model I associated it this way:
class Document < ApplicationRecord
has_many :translations_forms
...
end
But when I run the first command above, I getting this error:
NoMethodError: undefined method `relation_delegate_class' for Document::TranslationsForm:Class
I tried declaring the TranslationFrom Object adding the Document namespace
class Document::TranslationsForm
include ActiveModel::Model
belongs_to :document
def save(params: {})
return false if invalid?
self.document.translation.create(params)
end
end
But didn't work either, my TranslationForm object is in the app/forms/translations_form.rb
directory, and I'm using rails 6
, what can I do to associate the model with my form object?
Upvotes: 0
Views: 63
Reputation: 102026
A form object (which is a vague term) is usually just a variation of the Decorator pattern.
So you could simply setup the form object so that it wraps an instance of the model class:
class Document
class TranslationForm
include ActiveModel::Model
attribute_reader :document
def initialize(record = nil, attributes = {})
# lets you use the form object for existing records
if record
@document = record
@document.assign_attributes(attributes)
end
@document ||= Document.new(attributes)
end
def to_model
document
end
def save
# triggers validations on the form object
if valid?
document.save
else
false
end
end
end
end
def create
@document = Document::TranslationForm.new(document_params)
if @document.save
redirect_to @document
else
render :new
end
end
def update
@document = Document::TranslationForm.new(
Document.find(params[:id]),
document_params
)
if @document.save
redirect_to @document
else
render :edit
end
end
To add a validation to the form object (instead of directly to the model) just use delegatation:
class Document
class TranslationForm
# ...
validates :foo, presence: true
delegate :errors, to: :document
delegate :foo, to: :document
end
end
delegate :errors, to: :document
makes it so that your validations will add errors to the underlying model instead of the errors object of your form object.
Upvotes: 1