Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community!

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Treebook + Messaging // before_create callback not triggering

Adding a basic messaging system to my Treebook(plus!) app - based on this famous tutorial http://web.archive.org/web/20100823114059/http://www.novawave.net/public/rails_messaging_tutorial.html

At this point I have messages being saved and added to current_user's sent messages, but the before_create method that is supposed to create additional message copies for each recipient is getting skipped in the transaction.

Message model with before_create callback:

class Message < ActiveRecord::Base
 belongs_to :author, :class_name => "User"
 has_many :message_copies
 has_many :recipients, :through => :message_copies
 before_create :prepare_copies

 attr_accessor  :to
 attr_accessible :subject, :body, :to

 def prepare_copies
  return if to.blank?

  else
    to.each do |recipient|
      recipient = User.find(recipient)
      message_copies.build(:recipient_id => recipient.id, :folder_id => recipient.inbox.id)
  end
 end
end

Message Copy model:

class MessageCopy < ActiveRecord::Base
 attr_accessible :folder_id, :message_id, :recipient_id

 belongs_to :message
 belongs_to :recipient, :class_name => "User"
 belongs_to :folder
 delegate   :author, :created_at, :subject, :body, :recipients, :to => :message
end

Sent Controller:

class SentController < ApplicationController
  def index
    @messages = current_user.sent_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
  end

  def show
    @message = current_user.sent_messages.find(params[:id])
  end

  def new
    @message = current_user.sent_messages.build
  end

  def create
    @message = current_user.sent_messages.build(params[:message])

  if @message.save
    flash[:notice] = "Message sent."
    redirect_to :action => "index"
  else
    render :action => "new"
  end
 end
end

Sent/New view:

<%= simple_form_for :message, :url => {:controller => "sent", :action => "create"} do |f| %>

<p>
To:
<%= select_tag :to, options_from_collection_for_select(User.all, "id", "full_name", @message.to) %>
</p>

<p><%= f.input :subject %></p>
<p><br /> <%= f.input :body %></p>
<p><%= submit_tag "Send" %></p>
<% end %>

Here's the log showing the params passing through from the form and a message being created, but no copies prepared, etc.

Started POST "/sent" for 127.0.0.1 at 2013-03-07 00:25:55 -0500
Processing by SentController#create as HTML
Parameters: {"utf8"=>"?", "authenticity_token"=>"xPMFbWdg0thopyoov3yAnEa+N6fTcFNOpzAaJgXazd4=", "to"=>"6", "message"=>{"subject"=>"twat", "body"=>"tee"}, "commit"=>"Send"}

User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1

(0.2ms)  begin transaction

SQL (2.4ms)  INSERT INTO "messages" ("author_id", "body", "created_at", "subject", "updated_at") VALUES (?, ?, ?, ?, ?)  [["author_id", 5], ["body", "tee"], ["created_at", Thu, 07 Mar 2013 05:25:55 UTC +00:00], ["subject", "twat"], ["updated_at", Thu, 07 Mar 2013 05:25:55 UTC +00:00]]

(3.1ms)  commit transaction
Redirected to http://localhost:3000/sent
Completed 302 Found in 41ms (ActiveRecord: 6.4ms)

Figured I'd check with some fresh eyes. Thanks folks.

1 Answer

Nvm. Figured it out.