feature_flags 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -18,8 +18,11 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- with feature_flags gem you can easily manage different features in your rails application.You can turn on/off features.
21
+ For more info:[Click Here](http://ror-tech.blogspot.in/2013/08/manage-different-features-in-our-ruby.html)
22
+
23
+ ###For changes in new version(0.1.0):[Click Here](http://ror-tech.blogspot.com/2014/01/ruby-gem-featureflags-new-features-010.html)
22
24
 
25
+ with feature_flags gem you can easily manage different features in your rails application.You can turn on/off features.
23
26
 
24
27
  rails generate feature_flags:install
25
28
 
@@ -35,6 +38,10 @@ then do
35
38
  ##############################################################################
36
39
  FeatureFlags.enabled?(:feature_name) To check whether particular feature is enabled or not
37
40
 
41
+ FeatureFlags.enabled?([:feature_name1, :feature_name2, :feature_name3]) To check for multiple features
42
+
43
+ FeatureFlags.enabled_any?([:feature_name1, :feature_name2, :feature_name3]) To check if any of given features are enabled or not
44
+
38
45
  FeatureFlags.enable_all To enable all features in your app.
39
46
 
40
47
  FeatureFlags.disable_all To disable all features in your app.
@@ -43,7 +50,7 @@ then do
43
50
 
44
51
  FeatureFlags.create_and_enable(:feature_name) To create and enable feature
45
52
 
46
- FeatureFlags.enable(feature_name) To enable feature
53
+ FeatureFlags.enable(:feature_name) To enable feature
47
54
 
48
55
  ##############################################################################
49
56
 
@@ -60,6 +67,8 @@ If you want to generate views use,
60
67
  rails generate feature_flags:views
61
68
 
62
69
 
70
+ For Demo:[Click Here](http://feature-flags.herokuapp.com/)
71
+
63
72
  Here are some screenshots,
64
73
  main index view
65
74
 
@@ -1,8 +1,8 @@
1
1
  class FeatureFlagsController < ApplicationController
2
2
  layout FeatureFlags.configuration.layout.downcase
3
+ before_filter :load_features, :only => [:index,:create,:update,:destroy]
3
4
 
4
5
  def index
5
- @features = Feature.all
6
6
  end
7
7
 
8
8
  def new
@@ -14,7 +14,6 @@ class FeatureFlagsController < ApplicationController
14
14
  end
15
15
 
16
16
  def create
17
- @features = Feature.all
18
17
  @feature = Feature.new(params[:feature])
19
18
  respond_to do |format|
20
19
  if @feature.save
@@ -31,12 +30,21 @@ class FeatureFlagsController < ApplicationController
31
30
  end
32
31
  end
33
32
 
33
+ def enable_all
34
+ FeatureFlags.enable_all
35
+ end
36
+
37
+ def disable_all
38
+ FeatureFlags.disable_all
39
+ end
40
+
34
41
  def update
35
- @features = Feature.all
36
42
  feature = Feature.find(params[:id])
43
+ enabled_all = params[:enable_all].present? ? enable_all : false
44
+ disabled_all = params[:disable_all].present? ? disable_all : false
37
45
 
38
46
  respond_to do |format|
39
- if feature.update_attributes(params[:feature])
47
+ if enabled_all || disabled_all || feature.update_attributes(params[:feature])
40
48
  flash[:notice] = "#{feature.name} feature successfully updated"
41
49
  format.html{
42
50
  redirect_to feature_flags_url
@@ -58,7 +66,6 @@ class FeatureFlagsController < ApplicationController
58
66
  end
59
67
 
60
68
  def destroy
61
- @features = Feature.all
62
69
  feature = Feature.find(params[:id])
63
70
 
64
71
  respond_to do |format|
@@ -82,4 +89,8 @@ class FeatureFlagsController < ApplicationController
82
89
  end
83
90
  end
84
91
  end
92
+
93
+ def load_features
94
+ @features = Feature.all
95
+ end
85
96
  end
@@ -0,0 +1,21 @@
1
+ <%= form_for feature, :url => path, :method => method, :html => {:class => "feature-flag-form"} do |f| %>
2
+ <div class ="field">
3
+ <label>Name : </label> <br/>
4
+ <%= f.text_field :name %>
5
+ <div class ="errors">
6
+ <% if feature.errors.any? %>
7
+ <% feature.errors.full_messages.each do |error| %>
8
+ <%= error %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
12
+
13
+ </div>
14
+ <div class ="field">
15
+ <label>Status : </label>&nbsp;&nbsp;
16
+ <%= f.check_box :status %><label>Enabled </label> <br/>
17
+ </div>
18
+ <div class ="field">
19
+ <%= f.submit "Submit" %>
20
+ </div>
21
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <%= form_for feature, :url => feature_flag_url(feature), :method => :put, :html => {:class => "feature-flag-form",:style => "float:right;margin-right: 10px;display: inline-block"} do |f| %>
2
+ <%= hidden_field :enable_all,:value=> true %>
3
+ <%= f.submit "Enable All" %>
4
+ <% end %>
5
+ <%= form_for feature, :url => feature_flag_url(feature), :method => :put, :html => {:class => "feature-flag-form",:style => "float:right;margin-right: 10px;display: inline-block"} do |f| %>
6
+ <%= hidden_field :disable_all,:value=> false %>
7
+ <%= f.submit "Disable All" %>
8
+ <% end %>
@@ -7,26 +7,5 @@
7
7
 
8
8
  <div class="feature-div">
9
9
  <p style="font-weight:bold;font-size:23px">Update Feature</p>
10
- <%= form_for @feature, :url => feature_flag_path(@feature), :method => :put, :html => {:class => "feature-flag-form"} do |f| %>
11
- <div class ="field">
12
- <label>Name : </label> <br/>
13
- <%= f.text_field :name %>
14
- <div class ="errors">
15
- <% if @feature.errors.any? %>
16
- <% @feature.errors.full_messages.each do |error| %>
17
- <%= error %>
18
- <% end %>
19
- <% end %>
20
- </div>
21
-
22
- </div>
23
- <div class ="field">
24
- <label>Status : </label>&nbsp;&nbsp;
25
- <%= f.check_box :status %><label>Enabled </label> <br/>
26
- </div>
27
- <div class ="field">
28
- <%= f.submit "Submit" %>
29
- </div>
30
- <% end %>
31
-
10
+ <%= render :partial => "/feature_flags/form" , :locals => {:path => feature_flag_path(@feature),:method =>:put,:feature => @feature } %>
32
11
  </div>
@@ -14,7 +14,9 @@
14
14
 
15
15
  </div>
16
16
  <%= link_to "Add new Feature", new_feature_flag_path ,:style=>"float:right;margin-right: 50px;" %>
17
+ <%= render :partial => "/feature_flags/options", :locals => { :feature => @features.last } if @features.any?%>
17
18
 
19
+ <!--list of features start-->
18
20
  <div class="feature_flag">
19
21
  <center>
20
22
  <table id="features">
@@ -45,6 +47,10 @@
45
47
  </tr>
46
48
  <% end %>
47
49
  </tbody>
50
+ <%else%>
51
+ <tbody>
52
+ <tr><th colspan="10">Currently there are no features present!</th></tr>
53
+ </tbody>
48
54
  <% end %>
49
55
  </table>
50
56
  </center>
@@ -7,26 +7,5 @@
7
7
 
8
8
  <div class="feature-div">
9
9
  <p style="font-weight:bold;font-size:23px">Add new Feature</p>
10
- <%= form_for @feature, :url => feature_flags_path, :method => :post, :html => {:class => "feature-flag-form"} do |f| %>
11
- <div class ="field">
12
- <label>Name : </label> <br/>
13
- <%= f.text_field :name %>
14
- <div class ="errors">
15
- <% if @feature.errors.any? %>
16
- <% @feature.errors.full_messages.each do |error| %>
17
- <%= error %>
18
- <% end %>
19
- <% end %>
20
- </div>
21
-
22
- </div>
23
- <div class ="field">
24
- <label>Status : </label>&nbsp;&nbsp;
25
- <%= f.check_box :status %><label>Enabled </label> <br/>
26
- </div>
27
- <div class ="field">
28
- <%= f.submit "Submit" %>
29
- </div>
30
- <% end %>
31
-
10
+ <%= render :partial => "/feature_flags/form" , :locals => {:path => feature_flags_path,:method =>:post,:feature => @feature } %>
32
11
  </div>
@@ -4,7 +4,11 @@ require "feature_flags/configuration"
4
4
  require "feature_flags/manage_features"
5
5
  require "feature_flags/engine"
6
6
  require "active_support/dependencies"
7
+ require "feature_flags/feature_base"
8
+ require 'pstore'
9
+ require 'feature_flags/storage'
7
10
 
8
11
  module FeatureFlags
9
12
  # Your code goes here...\
13
+ FeatureFlags.update_pstore_value
10
14
  end
@@ -0,0 +1,53 @@
1
+ module FeatureFlags
2
+ module FeatureBase
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ after_save :update_hash
7
+ after_destroy :update_hash
8
+ end
9
+
10
+ @@features_hash = {}
11
+
12
+
13
+ #returns features hash
14
+ def self.features
15
+ ##checking value in pstore if false then update to true and update features_hash
16
+ pstore_value = get_pstore_value
17
+ @@features_hash = {} unless (pstore_value.present? && !defined? Rails::Console)
18
+
19
+ if(@@features_hash.present? && pstore_value.present?)
20
+ @@features_hash
21
+ else
22
+ set_hash
23
+ Feature.new.update_pstore_hash
24
+ end
25
+
26
+ @@features_hash
27
+ end
28
+
29
+ ###returns current value in pstore
30
+ def self.get_pstore_value
31
+ store = PStore.new('feature_flags')
32
+ store.transaction {store[:updated]}
33
+ end
34
+
35
+ #updates hash for features
36
+ def self.set_hash
37
+ @@features_hash = {}
38
+ Feature.all.map{|f| @@features_hash[f.name.to_s.intern] = f.status}
39
+ @@features_hash.freeze
40
+ end
41
+
42
+ def update_hash
43
+ FeatureFlags::FeatureBase.set_hash
44
+ update_pstore_hash
45
+ end
46
+
47
+ def update_pstore_hash
48
+ FeatureFlags.update_pstore_value(!defined? Rails::Console)
49
+ end
50
+
51
+
52
+ end
53
+ end
@@ -1,15 +1,15 @@
1
1
  module FeatureFlags
2
- def self.enabled?(feature_name)
3
- feature = Feature.where(:name => feature_name).last
2
+ def self.enabled?(feature)
3
+ feature.is_a?(Array) ? !check_features(feature) : get_feature(feature)
4
+ end
4
5
 
5
- if feature.present?
6
- feature.status? ? true : false
7
- else
8
- #Feature.create!(:name => feature_name, :status => true)
9
- #return true
10
- raise "#{feature_name} feature not found."
11
- end
12
-
6
+ def self.enabled_any?(features = [])
7
+ check_features(features, true)
8
+ end
9
+
10
+ ## checking dependant features
11
+ def self.check_features(features, check = false)
12
+ features.map{|feature| get_feature(feature)}.compact.include? check
13
13
  end
14
14
 
15
15
  def self.create_and_enable(feature_name)
@@ -19,38 +19,53 @@ module FeatureFlags
19
19
 
20
20
  def self.enable(feature_name)
21
21
  feature = Feature.where(:name => feature_name).last
22
- if feature.present?
23
-
24
- if feature.update_attributes(:status => true)
25
- return true
26
- else
27
- false
28
- end
22
+ throw_error(feature_name) unless feature.present?
23
+
24
+ if feature.update_attributes(:status => true)
25
+ return true
29
26
  else
30
- raise "#{feature_name} feature not found."
27
+ flash[:error] = "#{feature_name} could not be updated"
28
+ return false
31
29
  end
30
+
32
31
  end
33
32
 
34
33
  def self.set_disabled(feature_name)
35
34
  feature = Feature.where(:name => feature_name).last
36
- if feature.present?
35
+ throw_error(feature_name) unless feature.present?
37
36
 
38
- if feature.update_attributes(:status => false)
39
- return true
40
- else
41
- false
42
- end
37
+ if feature.update_attributes(:status => false)
38
+ return true
43
39
  else
44
- raise "#{feature_name} feature not found."
40
+ flash[:error] = "#{feature_name} could not be updated"
41
+ return false
45
42
  end
46
43
  end
47
44
 
45
+ #disables all features in application
48
46
  def self.disable_all
49
47
  Feature.update_all(:status => false)
48
+ Feature.last.update_attributes(:status => false)
50
49
  end
51
50
 
51
+ #enables all features in application
52
52
  def self.enable_all
53
53
  Feature.update_all(:status => true)
54
+ Feature.last.update_attributes(:status => true)
55
+ end
56
+
57
+ #fetch feature's status
58
+ def self.get_feature(feature_name)
59
+ all_features = FeatureFlags::FeatureBase.features
60
+ all_features.has_key?(feature_name) ? all_features[feature_name] : throw_error(feature_name)
61
+ end
62
+
63
+ def self.throw_error(feature_name)
64
+ raise "#{feature_name} feature not found."
65
+ end
66
+
67
+ def self.update_feature_hash
68
+ Feature.new.update_hash
54
69
  end
55
70
 
56
71
  end
@@ -0,0 +1,11 @@
1
+ module FeatureFlags
2
+
3
+ #storing toggle value inside pstore if in case someone updates from rails console
4
+ def self.update_pstore_value(updated = true)
5
+ store = PStore.new('feature_flags')
6
+ store.transaction do
7
+ store[:updated] = updated
8
+ end
9
+ end
10
+
11
+ end
@@ -1,3 +1,3 @@
1
1
  module FeatureFlags
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -31,6 +31,8 @@ module FeatureFlags
31
31
 
32
32
  def copy_feature_migration
33
33
  template "feature_flag_migrate.rb", "db/migrate/#{MigrationNumber.next_migration_number}_create_features.rb"
34
+
35
+ ##commented model file generation
34
36
  template "feature_flag_model.rb", "app/models/feature.rb"
35
37
  end
36
38
 
@@ -1,5 +1,4 @@
1
1
  class CreateFeatures < ActiveRecord::Migration
2
-
3
2
  def change
4
3
  #creating feature_flags table
5
4
  create_table(:features) do |t|
@@ -1,7 +1,13 @@
1
- class Feature< ActiveRecord::Base
1
+ class Feature < ActiveRecord::Base
2
2
 
3
+ #### IMPORTANT start ####
4
+ ### Dont remove this as this required for memoization of features...
5
+ include FeatureFlags::FeatureBase
6
+ #### IMPORTANT end ####
7
+
8
+
3
9
  validates :name, presence: true
4
10
 
5
11
  attr_accessible :name, :status
6
-
12
+
7
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feature_flags
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-30 00:00:00.000000000 Z
12
+ date: 2014-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -56,6 +56,8 @@ files:
56
56
  - README.md
57
57
  - Rakefile
58
58
  - app/controllers/feature_flags_controller.rb
59
+ - app/views/feature_flags/_form.html.erb
60
+ - app/views/feature_flags/_options.html.erb
59
61
  - app/views/feature_flags/edit.html.erb
60
62
  - app/views/feature_flags/index.html.erb
61
63
  - app/views/feature_flags/new.html.erb
@@ -65,7 +67,9 @@ files:
65
67
  - lib/feature_flags.rb
66
68
  - lib/feature_flags/configuration.rb
67
69
  - lib/feature_flags/engine.rb
70
+ - lib/feature_flags/feature_base.rb
68
71
  - lib/feature_flags/manage_features.rb
72
+ - lib/feature_flags/storage.rb
69
73
  - lib/feature_flags/version.rb
70
74
  - lib/generators/feature_flags/install_generator.rb
71
75
  - lib/generators/feature_flags/templates/feature_flag.rb
@@ -94,9 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
98
  version: '0'
95
99
  requirements: []
96
100
  rubyforge_project:
97
- rubygems_version: 1.8.18
101
+ rubygems_version: 1.8.23
98
102
  signing_key:
99
103
  specification_version: 3
100
104
  summary: Manage (turn on/off) different features in your rails app.
101
105
  test_files: []
102
- has_rdoc: