Rails gem - Public Activity for earlier posts - ruby

The gem does not recognize earlier post which were created before the gem was added.
It only started working, when fresh posts were created. Why was that?
And, how to have those earlier posts get covered by public_activity
Thanks.
Gem setup according to author site.

You've to create the old activities manually using create_activity method. I created a rake task for this.
task public_activity_migration: :environment do
User.find_each do |user|
[:comments, :friends].each do |relation|
user.send(relation).find_each do |obj|
obj.create_activity :create, owner: user, created_at: obj.created_at
print "."
end
end
end
end
The code above will create activities for the comment and friend model. If you're not using strong params you also need to allow the created_at attribute to be set on the PublicActivity::Activity model. This can be done by adding the following code before running your task.
class PublicActivity::Activity
attr_accessible :created_at
end

Related

Including shared example from rspec inside of cucumber

The end goal is to include the shared_examples.rb which is included in rails_helper.rb. shared_examples.rb is a copy of this file
https://github.com/tinfoil/devise-two-factor/blob/master/lib/devise_two_factor/spec_helpers/two_factor_authenticatable_shared_examples.rb
I want to reference the shared_examples.rb in my cucumber test so I can use the method it_behaves_like 'two_factor_authenticatable'
I have the following folder structure:
Updated to include #morissetcl suggested structure
features
step_definitions
sample_step.rb
support
env.rb
sample.feature
spec
models
user_spec.rb
support
shared_examples
shared_example.rb
rails_helper.rb
spec_helper.rb
Both the features and spec folders are at the root of my rails project.
I am trying to include inside the sample_step.rb file the rails_helper.rb which is located in the spec folder.
I tried using different types of require as shown below inside the sample_step.rb file.
require 'spec/spec_helpers/shared_examples'
require '../../spec/spec_helpers/shared_examples'
require_relative '../../spec/spec_helpers/shared_examples'
I keep getting the following error
undefined method `it_behaves_like' for main:Object (NoMethodError)
it_behaves_like is rspec specific. What it does is allow one spec to run another spec for a particular object, so that is not going to work in Cucumber.
What you need to do is have a test suite that has some cukes and some specs. You cover the two factor authentication in detail in rspec, and if you have to always use two factor authentication to login in your cukes you need to write a helper method so you can do that.
To do this I would do the following
Write some step definitions to support login, that delegate the work to a helper method.
Write the helper method
Have the helper method call additional methods to support two factor auth
Add the helper methods to cucumber's world object so they can be called in a step def
So
# features/step_defintions/login
module LoginStepHelper
def login(user: )
login_fill_form_and_submit(user: user)
login_two_factor(user: user)
submit_form
end
def login_fill_form_and_submit(user: )
fill_in :email, user.email
fill_in :password, user.password
end
def login_two_factor(user: )
code = retrieve_2factor_code(user: user)
fill_in :2factor, code
end
...
end
World(LoginStepHeler)
So now you have to work out how the test can get the 2factor code.
Once you have this done you have a tool your step definitions can use to login, so you can write things like
Given 'I am logged in' do
login user: #i
end
Given 'I login as Fred' do
login user: #fred
end
...
note: how many step defs can use your helper method.
You can find more detail about this approach here https://github.com/diabolo/cuke_up which includes details about how to create the test-users that we are passing into the login function in the above code
The solution I came up with was using some of the suggestions that #diabolist made. I looked into the shared examples file: https://github.com/tinfoil/devise-two-factor/blob/master/lib/devise_two_factor/spec_helpers/two_factor_authenticatable_shared_examples.rb
I then used the #validate_and_consume_otp! scenario and setup the data using the info in the before :each block.
The result was as so in my cucumber spec:
When('I fill in the login form with two factor code') do
Timecop.freeze(Time.current)
otp_secret = '2z6hxkdwi3uvrnpn'
#user.otp_secret = otp_secret
otp = ROTP::TOTP.new(otp_secret).at(Time.now)
#user.save # <- This is important to save it so the user has the otp you will pass
Timecop.return
fill_in 'user_email', with: 'user#example.com'
fill_in 'user_password', with: 'password'
fill_in 'user_otp_attempt', with: otp
click_button 'Login'
end
The setup can be cleaned up and put into a method just as #diabolist described so it can be reused by other tests.

Welcome emails in Ruby

I'm using Ruby and Devise:Confirmable. A day or so after a new user has registered and confirmed a new trial account we'd like to automatically send him or her a 'follow up email'. Is this something we should also do through devise, or is there a separate gem or process we should implement?
Since you are using Devise already, you can just overwrite the confirmation controller, try something like this.
class ConfirmationsController < Devise::ConfirmationsController
# GET /resource/confirmation?confirmation_token=abcdef
def show
super do |resource|
YourMailerClass.follow_up(resource).deliver_later(wait_until: 1.day.from_now) if resource.errors.empty?
end
end
end
You also need to update the routes.rb file, add the option controllers: { confirmations: :confirmations } at the end of the line where you define devise_for (restart your server after this).
I'm assuming you already have a background jobs proccesor, like sidekiq
Hope it helps

How to include id in slug using friendly_id

I am using friendly_id gem to have pretty urls in my application.I want an url like:
localhost:3000/posts/1/my-first-post
I want to do it using the friendly_id gem as i want to use the History module to avoid 404 error.I have tried but can't include the id in the slug.The code i am using is follows:
class Post < ActiveRecord::Base
extend FriendlyId
friendly_id :pretty_url, use: [:slugged, :history]
def pretty_url
"#{id}/#{title}"
end
end
But it is not including the id in the slug.Rather it is using the slug as if only title is used.
I think I remember reading somewhere that FriendlyId runs into issues with slashes within your slug function. Try "#{id}-#{title}" instead to see if that's the case.
The id of Post is set after the entry is saved. pretty_url doesn't work because the id doesn't exist yet.
You can get this behaviour without using the friendly_id gem by doing:
def to_param
"#{id} #{title}".parameterize
end

Riak and Ruby: Ripple not return valid entries

I want use riak with my sinatra application.
I'm using gem ripple, describe simple model and simple form for store data.
Then I want to show all saved entries, using "Article.all" all good, but when i store new entry and refresh page - list of entryies not updates until I restart my application.
I'm trying irb, trying sinatra\reloader, but nothing...
Then, I post new entry, it's momentaly appear in default riak rest interface, and when use riack-client directly all good.
require 'ripple'
require 'sinatra'
class Article
include Ripple::Document
property :title, String
property :body, String
end
get '/' do
#articles = Article.all
erb :articles
end
post '/' do
article = Article.new(:title => params[:title], :body => params[:body])
article.save
end
All is a costly operation in Riak and does not work. If u use the latest version of the Gem for github you will get a error stating the same.

How do I get cucumber and pickle working with mongo_mapper, machinist, and machinist_mongo?

I would like to get machinist, machinist_mongo, mongo_mapper, cucumber and pickle to play nice together.
Currently I have machinist with all my blueprints configured and am using cucumber to do BDD. So far so good. My problem is I am having to write custom cucumber steps for all of my machinist blueprints. It is not really a problem per se, since it is not stopping me in my tracks, but as a .NET dev checking out rails, it feels really dirty to have to write a step for each blueprint whereas in .NET I could probably use reflection.
Is there any way I can get pickle's built in capture_model, capture_plural_factory, etc, to recognize my machinist blueprints?
I am pretty confident I have machinist configured and set up correctly, because when I use blueprintname.make, in a custom cucumber step, everything works out correctly.
Gem versions:
rails 2.3.8
cucumber 0.8.3
cucumber-rails 0.3.2
mongo 1.0.5
mongo_mapper 0.8.2
pickle 0.3.0
machinist 1.0.6
machinist_mongo 1.1.1
features/support/pickle.rb:
require 'pickle/world'
Pickle.configure do |config|
config.adapters = [:machinist]
end
I tried using config.adapters = [:machinist, Machinist::MongoMapperAdapter] but I get an error stating that there is no method factories for Machinist::MongoMapperAdapter.
undefined method `factories' for Machinist::MongoMapperAdapter:Class (NoMethodError) /usr/local/lib/ruby/gems/1.8/gems/pickle-0.3.0/lib/pickle/config.rb:25:in `factories'
features/support/machinist.rb:
require 'machinist'
require 'machinist/mongo_mapper'
require "#{Rails.root}/spec/blueprints"
require 'database_cleaner'
Before { Sham.reset } # reset Shams in between scenarios
spec/blueprints.rb (truncated for clarity)
require 'sham'
require 'faker'
Sham.code { Faker::Lorem.words 1 }
AccessCode.blueprint do
code
end
app/models/access_code.rb
class AccessCode
include MongoMapper::Document
key :code, String, :required => true
end
After days of beating my head against the wall, I have everything mostly working (I say mostly working because I'm not sure if there is something wrong that I haven't discovered yet). The fix was actually pretty simple once I figured it out.
To resolve the issue, and get my cucumber steps working with pickle, I changed MongoMapper::Document to include Pickle::Adapter::Base. I used lib/pickle/adapters/active_record.rb and data_mapper.rb (same path as active_record.rb) that come with pickle as an example. I did still need machinist_mongo, presumably to hook up pickle to my machinist blueprints.
I can't take credit for the code in def self.model_classes - it is stolen from tjtuom's pickle fork.
PS. If this is the completely wrong way to do it, please feel free to criticize or give suggestions, I am a complete ruby noob.
module MongoMapper::Document
module PickleAdapter
include Pickle::Adapter::Base
def self.model_classes
##model_classes ||= ::MongoMapper::Document.descendants.to_a +
::MongoMapper::Document.descendants.map { |klass| klass.subclasses }.flatten
end
# get a list of column names for a given class
def self.column_names(klass)
klass.column_names
end
# Get an instance by id of the model
def self.get_model(klass, id)
klass.find(id)
end
# Find the first instance matching conditions
def self.find_first_model(klass, conditions)
klass.find(:first, :conditions => conditions)
end
# Find all models matching conditions
def self.find_all_models(klass, conditions)
klass.find(:all, :conditions => conditions)
end
end
end
Set up pickle for machinist:
Pickle.configure do |config|
config.adapters = [:machinist]
end
To configure database_cleaner for mongo:
require 'database_cleaner'
require 'database_cleaner/cucumber'
DatabaseCleaner.orm = 'mongo_mapper'
DatabaseCleaner.strategy = :truncation

Resources