views:

233

answers:

3

I've used Virtual attributes in the past but I can't seem to get past this, and I know the answer is probably staring me in the face.

I have a model like so:

model Confirmation.rb

class Confirmation < ActiveRecord::Base

  #attr_accessible :confirmation, :confirmation_token
  #attr_accessible :confirmation_token

  def confirmation_token
    confirmation.confirmation_token if confirmation
  end

  def confirmation_token=(token)
    self.confirmation = Booking.find_by_confirmation_token(token)
  end

end

Your average scaffold controller for

confirmations_controller.rb

  def new
    @confirmation = Confirmation.new(:confirmation_token => params[:confirmation_token])

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @confirmation }
    end
  end

new.html.erb

<h1>New confirmation</h1>

<% form_for(@confirmation) do |f| %>
  <%= f.error_messages %>

    <%= f.hidden_field :confirmation_token %>

...

routes.rb

  map.confirmation "confirmation/:confirmation_token", :controller => "confirmations", :action => "new"
  map.resources :confirmations

error

undefined method `confirmation=' for #

In the console Booking.find_by_confirmation_token(token) with a given token works perfectly fine.

Any ideas? suggestions?

+2  A: 

I think it should be either:

def confirmation_token=(token)
    @confirmation = Booking.find_by_confirmation_token(token)
end

Or you should uncomment attr_accessible :confirmation or define #confirmation and #confirmation=.

Koraktor
that's odd. I tried the same thing once before... with @ instead of self... and it didn't work. But this time it did. Still not sure what changed.. thanks.
holden
A: 
class Confirmation < ActiveRecord::Base
  belongs_to :bookings

  #attr_accessible :confirmation, :confirmation_token
  #attr_accessible :confirmation

  def confirmation_token
    @confirmation.confirmation_token if @confirmation
  end

  def confirmation_token=(token)
    @confirmation = Booking.find_by_confirmation_token(token)
  end

end

this worked... however just uncovering the attr_accessible :confirmation, did not. self.confirmation still returned undefined method...

holden
i'd still like to know why?
holden
attr_accessible is only for mass assignment via Model#attributes. It doesn't define getters/setters.attr_accessor is doing that.
Koraktor
ah, perfect. now it works as intended!
holden
+1  A: 

What you really need is attr_accessor :confirmation. There's a difference between attr_accessible and attr_accessor.

attr_accessor :confirmation

is same as

def confirmation
  @confirmation
end

def confirmation=(value)
  @confirmation = value
end

Now since it's such a common pattern ruby introduced helper methods for that.

Attr_accesible on the other hand is rails method, which marks that certain fields can be mass updated.

Andrius