LoadError Unable to autoload constant Message
Asked Answered
D

4

65

In my app; when I submit form, I get this error:

LoadError at /questions
Unable to autoload constant Message, expected /app/models/message.rb to define it

It points to the create action in the Questions controller:

@message = current_user.messages.new(:subject => "You have a question from #{@question.sender_id}"`

Message model:

class Mailboxer::Message < ActiveRecord::Base
  attr_accessible :notification_id, :receiver_id, :conversation_id
end
Dissimilar answered 20/6, 2014 at 16:35 Comment(8)
It looks like a namespace issue. How is the relationship between user and messages defined, and where is the Message model defined?Gauntlet
@Sharagoz If I remove the Mailboxer:: from the name I get the error Table 'dating_development.messages' doesn't exist. Which makes sense since there is no messages table, only a notifications table. I just realized Mailboxer::Message should go into a subdirectory, but I'm going on the wrong path if I start going down that road.Dissimilar
Can you share the User model in the question.Boor
@pwz2000, please share ` Question Model `Britnibrito
@KirtiThorat user model addedDissimilar
@Acacia Question model addedDissimilar
@Dissimilar You're trying to treat the Message class as an ActiveRecord model. If the message class does not map to a database table then you cannot refer to it from the User model as an association. That's why you're getting the errors you see.Hepner
For starters, I just notice I'm not suppose to have a Message model with Mailboxer. So that has been removed. In the controller I did add the line under the create action @conversation = Conversation.create! to see what kind of error I will get. It gives me a ActiveRecord::RecordInvalid that says Validation failed: Subject can't be blank. So my thought is it has something to do with the Question model.Dissimilar
A
117

By convention in rails (and this is enforced by autoloader), file paths should match namespaces.

So, if you have a Mailboxer::Message model, it should be in app/models/mailboxer/message.rb.

Additionally, you probably have autoloader kicking in when trying to load a Message class (my guess is that it happens from within ActAsMessageable). It looks for a message.rb file in the load path, finds it in app/model/ and thus loads that file so it can find the Message class.

Problem is, it doesn't find a Message class in that file, only a Mailboxer::Message class (which is different). This is why it throws "Unable to autoload constant Message, expected /app/models/message.rb to define it".

To fix that, create directory app/models/mailboxer/ and put Mailboxer::Message in it.

Aikens answered 24/6, 2014 at 16:7 Comment(3)
Thanks for the insight. I removed the message model as it was not needed to begin with, but your point is 100% correct.Dissimilar
YESSSSSSSS! My week long search is over. This is so uncomfortably correct!Consonant
I had a case mismatch in the class name: I was referencing API:: instead of Api::Essence
J
3

I got this during integration testing. Turns out, it was fixtures related. Had to delete the my unused file in /test/fixtures/wrong_name.yml

Jordanna answered 31/1, 2018 at 20:30 Comment(1)
Same thing here... I could have spent hours to find the culprit. Thanks a lot. This is an example of magic turning into insanity...Caudill
C
1

As stated in the documentation, to send a message from A model to B model you have to add:

acts_as_messageable 

in both models.

And then do:

a.send_message(b, "Body", "subject")

So in your models:

  class User < ...
    act_as_messageable
  end

@question_sender must be a User instance.

@question_sender.send_message({attr_accessor_hash}, recipient_user, @question.body, "You have a question from #{@question_sender.id}")

As long as the attr_accessor is not related to the gem, and the method send_message is not aware of this attributes you will have to redefine it:

https://github.com/mailboxer/mailboxer/blob/master/lib/mailboxer/models/messageable.rb#L60

add the attr_accessor_hash to method

def send_message({attr_accesor_hash}, recipients, msg_body, subject, sanitize_text=true, attachment=nil, message_timestamp = Time.now)

And look at the code add the fields where you need as: attr_accessor["param"]

Chengteh answered 20/6, 2014 at 19:0 Comment(7)
It points to undefined method `attr_accessible' for Message:ClassDissimilar
I am unable to use accessor without ActiveRecord as it gives the error undefined method `arel_table’ which points to the line @message = current_user.messages.new. Adding AR back to the model will give me Table 'dating_development.messages' doesn't exist which also points to the same line.Dissimilar
Are you using any gem? This datin_development table is not pasted anywhere but in the error.Chengteh
Yes, I am using the mailboxer gem. The Questions controller is on it's own, I am trying to make it connect to the Mailboxer so when a User fills out the Question form it will then create a message to recipient with the details of the message inside (body of the message will be the Question).Dissimilar
Then the question should contain that info. I wasn't aware of that gem :| Let me check the info!Chengteh
My apologizes! Any help would be appreciated :) I will keep digging into it myself of courseDissimilar
Let us continue this discussion in chat.Chengteh
B
0

Notice these lines;

@question = Question.new(params[:question])

@question.message = @message

and ;

attr_accessible :answer, :question, :sender_id, :recipient_id, :conversation_id

The @question.message line is calling an attribute that is not accessible in the Question Model so do this;

attr_accessible :answer, :question, :sender_id, :recipient_id, :conversation_id, message
Britnibrito answered 20/6, 2014 at 19:55 Comment(1)
I tried that before. It points to the same error unfortunately. I think it has something to do with the Message model I had to create.Dissimilar

© 2022 - 2024 — McMap. All rights reserved.