Wicked Wizard dynamic step order - ruby-on-rails-4

I'm trying to alter the order of the steps in wicked wizard based on the selections form a previous selection.
So currently I have all the steps:
class WWTestController < ApplicationController
include Wicked::Wizard
steps :first_page,:optional_page,:second_page
def show
#event_object = EventObject.find(params[:event_object_id])
render_wizard
end
def update
#event_object = EventObject.find(params[:event_object_id])
#event_object.update_attributes(event_object_params)
render_wizard #event_object
end
private
def event_entry_params
params.fetch(:event_object, {}).permit(:choice_a)
end
end
I want to only include the step :optional_page if they have selection :choice_a to equal 2. I've tried various configs but the real issue I run into is if they go back to the :firstpage and change the steps aren't always correct. I'm sure someone has a good approach to this, any help would be greatly appreciated!!!

def show
#event_object = EventObject.find(params[:event_object_id])
# Extra logic based on flow steps - when to skip sth.
case step
when :optional_page
skip_step unless #event_object.choice_a == 2
end
render_wizard
end

Related

Rails not saving in controller

I want to get a view count for every time a photo is viewed. This is my show method, not sure why this doesn't work, seems pretty straight forward. The branch is called every time, but the database is not bing update...
def show
if current_user.nil? || #photo.profile != current_user.profile
#photo.views += 1
#photo.save!
end
render layout: 'layouts/photo'
end
The problem here is that #profile is simply not specified.
You may want to do something like the following:
def show
#profile = Profile.find(params[:id])
if #profile && current_user.nil? || #photo.profile != current_user.profile
#profile.views += 1
#profile.save
end
render layout: 'layouts/photo'
end
Besides that it's probably best to use a gem for that matter. I suggest impressionist. It will handle the most important stuff for you and block bots. It also offers additional features you may want.

Pundit::AuthorizationNotPerformedError attempting to adapt microposts to Devise/Pundit

I'm new to Rails and I'm working through Michael Hartl's excellent Rails Tutorial for a second time, this time I'm trying to adapt the chapter 11 and chapter 12 microposts to a simple Devise/Pundit application I'm working on. I am able to create microposts through the seed file and display them, but I'm getting an authorization error with Pundit when I actually try to create a new post through the site. The error I'm getting is:
Pundit::AuthorizationNotPerformedError in MicropostsController#create
My Microposts Controller looks like this:
class MicropostsController < ApplicationController
before_action :authenticate_user!
after_action :verify_authorized
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to current_user
else
#feed_items = []
flash[:danger] = "Unable to create micropost!"
end
end
def destroy
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
end
I'm thinking that do not have the authorization set up properly for the 'create' action, but I'm not sure exactly how it should be set. I do not have a policy for Pundit for Microposts. I tried adding a simple one but it didn't change anything. I'm learning to put all these pieces together, would someone point me in the right direction?
There is one after action filter verify_authorized because of which you are getting this error. If you have created a policy for the create action then use that to get rid of the error.

Rails - Tracking non-logged in user activity

Say an application has many Products and searching capabilities.
1. How can I track page views on each product(a simple counter) and
2. how can I track search queries as well?
Most importantly, I need to be able to find/order products by number of page views.
The (simpler / best performance / least outside dependency) the better!
Why this question? The solutions I've seen so far are either out of date gems or don't work well with searching.
Here's a simple way to do it. In the model:
def increment(by = 1)
self.views ||= 0 #Prevents error if views can be nil
self.views += by
self.save
end
Then in the controller:
#model.increment
Faster if made into an asynchronous job which I still need to do.
To prevent users spamming refresh or something I made it a bit more complicated:
def show
product_itemcode = params[:itemcode]
#product = Product.find_by(itemcode: product_itemcode)
unless session[product_itemcode.to_s]
#product.increment
session[product_itemcode.to_s] = true
end
end
Any thoughts?
EDIT:
An increment method already exists:
http://apidock.com/rails/ActiveRecord/Persistence/increment
You still have to call object.save though

Why is Digest::SHA1 preventing proper annotation of a model?

I am using annotate in my app and all models are successfully annotated except for user.rb, which shows the following error when I annotate:
Unable to annotate user.rb: wrong number of arguments (0 for 1)
Outside of annotating, everything else works fine. User creation, updating, deletion, login, sign out, it all works properly. I have determined that the problem is with the Digest::SHA1, which I use to create session tokens, as demonstrated below in the snippet from user.rb.
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.hash(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
remember_token = User.hash(User.new_remember_token)
end
If I remove the second (def User.hash(token)) and instead do the following:
def User.new_remember_token
SecureRandom.urlsafe_base64
end
private
def create_remember_token
remember_token = Digest::SHA1.hexdigest(User.new_remember_token.to_s)
end
then annotate is happy and successfully annotates user.rb. However, this isn't really the ruby way as my session helper utilizes that User.hash(token) call several times. What am I not understanding about Digest::SHA1.hexdigest or the way that I am utilizing it?
Looks like you're working through The Rails Tutorial.
The likely reason you're seeing issues with your User.hash method is nothing to do with Digest::SHA1, but is because the method itself is inadvertently overriding Ruby's Object#hash method, which is giving you some cryptic errors. Link to Github issue about it.
So, like this commit to the Sample App repository, rename all your instances of User.hash to User.digest and hopefully that should fix your errors.

Redmine - Add "Spent Time" Field to Issues Display

How would I go about adding the "Spent Time" as a column to be displayed in the issues list?
Consolidating Eric and Joel's answers, this is what I needed to do to get a 'Spent time' column added to Redmine 1.0.3. Not sure if there's a better way to get the translation text added.
To give the new field a localised name, added to config/locales/en.yml around line 299 at the end of the field definitions:
field_spent_hours: Spent time
To add the new column, created lib/spent_time_query_patch.rb with content:
# Based on http://github.com/edavis10/question_plugin/blob/master/lib/question_query_patch.rb
require_dependency 'query'
module QueryPatch
def self.included(base) # :nodoc:
base.extend(ClassMethods)
# Same as typing in the class
base.class_eval do
unloadable # Send unloadable so it will not be unloaded in development
base.add_available_column(QueryColumn.new(:spent_hours))
end
end
module ClassMethods
unless Query.respond_to?(:available_columns=)
# Setter for +available_columns+ that isn't provided by the core.
def available_columns=(v)
self.available_columns = (v)
end
end
unless Query.respond_to?(:add_available_column)
# Method to add a column to the +available_columns+ that isn't provided by the core.
def add_available_column(column)
self.available_columns << (column)
end
end
end
end
To get the spent_time_query_patch above to actually load, created config/initializers/spent_time_query_patch.rb with content:
require 'spent_time_query_patch'
Query.class_eval do
include QueryPatch
end
You can also do this by adding the column at runtime. This will add the spent hours column without modifying the Redmine core. Just drop the following code into a file in lib/
Adapted from:
Redmine Budget Plugin
Redmine Question Plugin
require_dependency 'query'
module QueryPatch
def self.included(base) # :nodoc:
base.extend(ClassMethods)
# Same as typing in the class
base.class_eval do
unloadable # Send unloadable so it will not be unloaded in development
base.add_available_column(QueryColumn.new(:spent_hours))
end
end
module ClassMethods
unless Query.respond_to?(:available_columns=)
# Setter for +available_columns+ that isn't provided by the core.
def available_columns=(v)
self.available_columns = (v)
end
end
unless Query.respond_to?(:add_available_column)
# Method to add a column to the +available_columns+ that isn't provided by the core.
def add_available_column(column)
self.available_columns
Also, it would be cool, if the column "Spent time" was sortable.
After looking up the produced SQL, I just implemented the sortable feature this in this way:
base.add_available_column(QueryColumn.new(:spent_hours,
:sortable => "(select sum(hours) from time_entries where time_entries.issue_id = t0_r0)")
)
Replace the respective line. I just hope the issue_id column's name is always "t0_r0" ...
PS: You can find lots of examples in app/models/query.rb lines 122++
2-Digits Problem:
Unfortunatly, I had to hack one of the core files: app/helpers/queries_helper.rb
Around line 44, change this:
when 'Fixnum', 'Float'
if column.name == :done_ratio
progress_bar(value, :width => '80px')
else
value.to_s
end
into:
when 'Fixnum', 'Float'
if column.name == :done_ratio
progress_bar(value, :width => '80px')
elsif column.name == :spent_hours
sprintf "%.2f", value
else
value.to_s
end
EDIT: Using a patch instead manipulating the source Recently, we did an update of the redmine system, so the above mentioned Fix also was removed.
This time, we decided to implement that as a patch.
Open up any plugin (We created a plugin for our monkey-patch changes on core). open up vendor/plugins/redmine_YOURPLUGIN/app/helpers/queries_helper.rb
module QueriesHelper
def new_column_content(column, issue)
value = column.value(issue)
if value.class.name == "Float" and column.name == :spent_hours
sprintf "%.2f", value
else
__column_content(column, issue)
end
end
alias_method :__column_content, :column_content
alias_method :column_content, :new_column_content
end
This feature build in from 1.4.0 version
by using AgileDwarf plugin. You can have spent time & you can say for what you spent this time (developement - design -...)
Since no one answered, I just poked the source until it yielded results. Then I started a blog to explain how I did it.
Add spent time column to default issues list in Redmine