Sessionshelper in Railstutorial.Org: Should Helpers Be General-Purpose Modules for Code Not Needed in Views

SessionsHelper in railstutorial.org: Should helpers be general-purpose modules for code not needed in views?

Indeed, your feeling is correct.

I would implement this the other way around: add the functions sign_in and current_user to ApplicationController (or if you really want to: in a separate module defined in lib and include it), and then make sure that the current_user method is available in the view.

In short:

class ApplicationController

helper_method :current_user

def sign_in

end

def current_user
@current_user ||= user_from_remember_token
end
end

Of course, if you have a lot of code to place into your ApplicationController it can get messy. In that case I would create a file lib\session_management.rb:

module SessionManagement
def self.included(base)
base.helper_method :current_user
end

def sign_in
..
end

def current_user
..
end
end

and inside your controller you can then just write:

class ApplicationController
include SessionManagement
end

Ruby on Rails Chapter 9 Errors

Your error is because there is no sign_out method defined in your SessionsController or in the parent ApplicationController it inherits from.

According to the Rails tutorial in chapter 8 he has you define this method in the SessionsHelper, which is then mixed in to the ApplicationController. I think mixing helpers into controllers is not good (helpers should be restricted to views; others agree), but that's the way the tutorial is laid out for you.

Ruby on Rails: ApplicationController methods undefined? (beginner)

inside your application.rb put this

class ApplicationController
include SessionsHelper
end

Also refer this SessionsHelper in railstutorial.org: Should helpers be general-purpose modules for code not needed in views?

Need a simple, DRY, general-purpose checkpointing mechanism

After mulling it over, I deciding that I'm willing to make this specific to ActiveRecord. By exploiting ruby's ensure facility and the destroyed? and changed? methods in ActiveRecord, the design becomes simple:

define Checkpoint model with :name and :state

# file db/migrate/xyzzy_create_checkpoints.rb
class CreateCheckpoints < ActiveRecord::Migration
def change
create_table :checkpoints do |t|
t.string :name
t.string :state
end
add_index :checkpoints, :name, :unique => true
end
end

# file app/models/checkpoint.rb
class Checkpoint < ActiveRecord::Base
serialize :state
end

define WithCheckpoint module

# file lib/with_checkpoint.rb
module WithCheckpoint

def with_checkpoint(name, initial_state, &body)
r = Checkpoint.where(:name => name)
# fetch existing or create fresh checkpoint
checkpoint = r.exists? ? r.first : r.new(:state => initial_state)
begin
yield(checkpoint)
ensure
# upon leaving the body, save the checkpoint iff needed
checkpoint.save if (!(checkpoint.destroyed?) && checkpoint.changed?)
end
end
end

sample usage

Here's a somewhat contrived example that randomly blows up after some number of iterations. A more common case might be a lengthy network or file access that can fail at any point. Note: We store the state in an array only to show that 'state' needn't be a simple integer.

class TestCheck
extend WithCheckpoint

def self.do_it
with_checkpoint(:fred, [0]) {|ckp|
puts("intial state = #{ckp.state}")
while (ckp.state[0] < 200) do
raise RuntimeError if rand > 0.99
ckp.state = [ckp.state[0]+1]
end
puts("completed normally, deleting checkpoint")
ckp.delete
}
end

end

When you run TestCheck.do_it, it might randomly blow up after some number of iterations. But you can re-start it until it completes properly:

>> TestCheck.do_it
intial state = [0]
RuntimeError: RuntimeError
from sketches/checkpoint.rb:40:in `block in do_it'
from sketches/checkpoint.rb:22:in `with_checkpoint'
...
>> TestCheck.do_it
intial state = [122]
completed normally, deleting checkpoint
=> #<Checkpoint id: 3, name: "fred", state: [200]>


Related Topics



Leave a reply



Submit