I’m at the end of the third lesson and have a problem with the validation of new TextShouts.
The problem is that I’m able to create a Shout with the content type TextShout where the TextShout has no body.
Thus, I get the following error afterwards:
ArgumentError in Dashboards#show
Showing .../thoughtbot/intermediate-rails/app/views/shouts/_shout.html.erb where line #6 raised:
'nil' is not an ActiveModel-compatible object that returns a valid partial path.
The linked repo is private so can’t have a look. I guess issue is the content_id is nil and you would render a different partial based on that? I am just shooting blank since I don’t participate in that workshop.
Do you have a validation rule for that field on the model?
From your console example I suppose you don’t. You need to add something like this to the ShoutBox model:
I spent some time yesterday figuring out a solution to this problem so I thought I might as well post it here.
The problem is that validations run before either record is saved, so there won’t ever be a content_id when a new shout is being validated. The answer I came up with was to create a custom validator to check content.valid?, like so:
class TextShout < ActiveRecord::Base
validates :body, presence: true
end
class Shout < ActiveRecord::Base
belongs_to :user, required: true
belongs_to :content, polymorphic: true, required: true, dependent: :destroy
validate :content_must_be_valid
default_scope { order(created_at: :desc) }
protected
def content_must_be_valid
if content && content.invalid?
content_errors = content.errors.full_messages.join(", ")
errors.add(:content, "not valid: #{ content_errors }")
end
end
end
Works for me. Would love to know if there’s a better way, though.