I am using the public_activity gem to generate activity feeds in my app, and in my model, I am using devise's current_user to identify the owner of the activity.
class Question < ActiveRecord::Base
...
include PublicActivity::Model
tracked owner: ->(controller, model) { controller.current_user }
...
end
I realize that referencing current_user in the model is not the norm, but this is how they recommend doing it.
This works fine in the app, but I am running into trouble with my Rspec tests, where I get the following error:
Failure/Error: expect(create(:question)).to be_valid
NoMethodError:
undefined method `current_user' for nil:NilClass
# ./app/models/question.rb:8:in `block in <class:Question>'
# ./spec/models/question_spec.rb:7:in `block (3 levels) in <top (required)>'
The test itself is typical:
describe "Factory" do
it "has a valid factory" do
expect(create(:question)).to be_valid
end
end
Here is my factory:
FactoryGirl.define do
factory :question do
title { Faker::Lorem.characters(30) }
body { Faker::Lorem.characters(150) }
user_id { 1 }
tag_list { "test, respec" }
end
end
How do I get this current_user method in my model to work in my tests?
Personally I don't think you should reference the controller
from within the model
. Because you don't want to instantiate a controller
object every time you want to access the model
.
For example you might want to access the model
from a background worker: who's your current_user
and what's your controller
?
The same applies to your test suite. You want to test your model
, not your controller
.
Also you might not always want to track activity.
A better approach is to pass in the current_user
object from the controller
. Ryan Bates has a nice example in his Railscast on Public Activity (see "Excluding Actions"):
class Question < ActiveRecord::Base
include PublicActivity::Common
end
And for every activity you want to track
@question.create_activity :create, owner: current_user