Can't Install Vanity A/B Testing on Rails - ruby-on-rails

I'm trying to install Vanity A/B Testing in my Rails App, but I can't even get the example from the GitHub page working. I've generated the vanity models and run the migrations and made the experiment files, but as soon as I include a test like
<%= ab_test :price_options %>
the program throws an error:
invalid value for Integer(): "{:conditions=>{:experiment_id=>\"price_options\""
In my controllers/application_controller.rb I have just:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
use_vanity
end
I didn't include a user identifier because I haven't built one into this app yet, but the Vanity docs say that if no argument is supplied Vanity will just use cookies instead, so that shouldn't be an issue. If anyone has any clue why this cryptic error is being thrown, I would be very appreciative!
Edit: I should add that I actually started a new rails app from scratch just to try and debug this. Literally all I did was start an app and install vanity following the readme instructions and I got this same error. This has happened on two different machines as well, so I suspect it's something obvious that I'm missing, but I can't be sure (else I wouldn't be here!).
EDIT: I've since decided to use the Split gem instead, and am having no troubles with it.

This error is thrown because the current release version of Vanity uses the deprecated Rails find(:first) method, specifically:
VanityParticipant.first(:conditions=>{ :experiment_id=>experiment.to_s, :identity=>identity.to_s })
This no longer works with Rails 4.1 but is fixed in the master branch of Vanity, so you can get round this in your Rails 4.1 app by adding:
gem 'vanity', :git => 'git#github.com:assaf/vanity', :branch => 'master'
to your Gemfile.

With
class ApplicationController < ActionController::Base
protect_from_forgery
use_vanity
end
and
# experiments/price_options.rb
ab_test "Price options" do
description "Mirror, mirror on the wall, who's the best price of all?"
alternatives(19, 25, 29)
end
and
class StaticController < ApplicationController
def home
end
end
the following view loads and sets a vanity_id cookie:
<h1>Static#home</h1>
<p>Find me in app/views/static/home.html.erb</p>
<h2>Get started for only $<%= ab_test :price_options %> a month!</h2>
<%= link_to 'Make a new account', new_account_path %>

Related

Rails Delete_All but Still Looking for id=5

I recently switched my app from a gem to a by-hand shopping cart. I created a new orders table, yet when I try to get into my app I get an error saying:
ActiveRecord::RecordNotFound at /
Couldn't find Order with 'id'=5
The error is called on this bit of my application_controller:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_order
def current_order
if !session[:order_id].nil?
Order.find(session[:order_id]) <<<<< THIS LINE
else
Order.new
end
end
end
I tried order.delete_all in my controller, but it is still looking for id=5 for some reason. I would try db:drop db:create but I have data on the production app I don't want to lose.
Is there any way to either:
Fix this error without messing up the database?
Drop/recreate just the orders table without destroying the rest of the database?
Also, I could be reading the problem wrong, so let me know if you think the solution lies elsewhere.
The problem has nothing to do with database at all. Well, almost. Certainly, nothing that will require dropping/recreating db structures.
Your session[:order_id] has a value that is not in the db. That's what you have to fix, the session. Or your handling of not-found records. For example, this will not raise an error.
Order.where(id: session[:order_id]).first

Session Values getting reset after redirect rails 4

I am using devise 3.5.1, rails 4.0.0 and ruby 2.0.0-p0.
If a user is not signed in and tries to open a private page which requires authentication, let's say lvh.me:3000/users/1/edit, then devise will add users/1/edit in session against the key user_return_to. The problem is that when the user gets redirected to the login page after authentication failure then user_return_to value in session gets reset.
I have this problem all over my app. If I store a value in session and redirect to another path from the same action then the session value disappears.
Note: I have upgraded my rails app from (rails 3.0.4, ruby 1.8.7) to (rails 4.0.0, ruby 2.0.0).
Sorry for any ambiguities in the question. If you have any question please comment it.
UPDATE:
In my application controller, I've added a before filter to authenticate user. Only relevant code is shown in application controller.
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate_user!, :unless => :devise_controller?
# rest of the code
end
I'm using a custom failure class which inherits Devise::FailureApp. The code looks like this.
custom_failure.rb
class CustomFailure < Devise::FailureApp
def redirect_url
eval "new_user_session_path"
end
def redirect
store_location!
flash[:alert] = i18n_message
# session[:user_return_to] returns '/foobar' here.
redirect_to redirect_url
end
end
I have commented a line in above code. session[:user_return_to] is available at that line but after the redirect on very next line, the session[:user_return_to] becomes nil.
I've upgraded devise from 1.5.3 to 3.5.1.
I'm adding the solution here in case anybody else encounters the same problem.
I had a resource named asset in my application and it was conflicting with the asset pipeline. The session was getting reset whenever my URL contained 'assets' e.g. '/assets'. So if you have a resource named asset then you have to change the prefix of your asset pipeline. To do so, add the following line in your application.rb file.
config.assets.prefix = '/static_assets'
Also you have to rename the asset pipeline folder to static_assets.
Please note that this solution only applies if you have a resource named Asset in your application and the rails version is 3.1+

Ruby on rails before_filter function not executing

So there's a bit of code that I want to execute on every request that is made to my rails application and found through googling that I can do it using before_filter. Buy it doesn't seem to run when I go to the initial page, which is localhost:3000. Anyone know why it doesn't run?
I'm using Ruby on Rails 3, WebBrick server on Lubuntu Linux.
class ApplicationController < ActionController::Base
before_filter :run
private
def run
logger.debug "run? I'm too tired"
end
end
If your initial page is a 'static' page served from the public directory this code will not be run. To fix, make the page render as the result of some controller's action that inherits from ApplicationController.

cant get cancan to work on rails 3.1

I had a two month break using Rails and now its biting me when I return!
I am trying to get CanCan to work on Rails 3.1 and have viewed the railscast and then followed their instructions on the cancan git page. However when I try run the homepage it gives me the following error:
Routing Error
undefined local variable or method `authorize_resource' for StaticController:Class
How do I make this stop? Its as if cancan is not loaded, but I have installed it using bundler and it doesnt mention that I have to do anything else to include it.
Anyone have any ideas?
Sorry my bad! Too much coffee resulted in me not reading all the instructions for how to install it.
I needed to add the following to my ApplicationController:
def current_ability
#current_ability ||= Ability.new(current_user)
end
and then I needed to use
class StaticController < ApplicationController
authorize_resource :class => false
Because in this particular example it was just a static simple homepage that sits infront of a more complicated web app.
Thanks for the help.

How to restrict public access to a rails app

Is there a way to upload an app, but only have it accessible by me? Or perhaps by a specific set of IP's?
Reason being, we want to run a few private online tests before opening the app up to the general public. So far I have come up with the following code:
class ApplicationController < ActionController::Base
before_filter :restrict_access
def restrict_access
whitelist = ['127.0.0.123', '10.0.1.7', '10.0.1.8'].freeze
unless( whitelist.include? request.env['REMOTE_ADDR'] )
render :file => "#{Rails.public_path}/500.html", :status => :unauthorized
return
end
end
end
However, the above code still renders the main layout file (app/views/layouts/application.html.erb) which exposes the logo and footer. For un-authorised access we want to display a page that says something like "Ooops, we are still doing a few tests and will be public soon!". No logo of the site, no nothing. Just a simple message.
We are using devise as our authentication gem. We don't want to add authentication functionality just to restrict access for private beta testing. We want to do it by IP instead.
Is such a thing possible? Perhaps the code above just needs working on? Or is there a gem that we can use solely for this requirement?
If you're deploying on Apache or Nginx, this should be easy enough to configure in the relevant site config files. Doesn't need to be in the app itself, in that case.
I'm not totally sure what the issue is with your existing code. Are you saying that the filter seems to be ignored, or that the file renders within the layout? If it's the latter, specifying :layout => false as a render option should take care of that.
class ApplicationController < ActionController::Base
before_filter :check, :except=>:unauth
def unauth
render(:layout=>false)
end
private
def check
whitelist = ['127.0.0.123', '10.0.1.7', '10.0.1.8'].freeze
if !(whitelist.include? request.env['REMOTE_ADDR'])
redirect_to('/unauth')
return
end
end
end
untested but should do it, now you can place a plain error msg or whatever in unauth.rhtml
I will suggest of use some Rack middelware a.e. rack-rewrite
require 'rack-rewrite'
#in your environment
config.middleware.insert_before(Rack::Lock, Rack::Rewrite) do
r301 %r{.*}, "YOUR REDIRECTPAGE$&" ,:if => Proc.new {|rack_env|
#puts here your conditions basing on rack_env
}
end
NOT TESTED

Resources