Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit f9b2cc11bbb2b9bdfeedb5318e232a19250aa090 0 parents
@sutetotanuki authored
9 .gitignore
@@ -0,0 +1,9 @@
+.bundle
+vendor
+Gemfile.lock
+
+.DS_Store
+*~
+\#*
+.\#*
+*.gem
1  .rspec
@@ -0,0 +1 @@
+-fs -c
2  Gemfile
@@ -0,0 +1,2 @@
+source :rubygems
+gemspec
33 README.md
@@ -0,0 +1,33 @@
+# まめちわ
+まめ ちわわ
+
+## 使い方
+```
+class Group < ActiveRecord::Base
+ mamechiwa :options, :group_type do
+ mame_group "group1" do
+ mattr :group_1_attr
+
+ define_validator do
+ validates :group_1_attr, presence: true
+ end
+ end
+
+ mame_group "group2" do
+ mattr :group_2_attr_1
+ mattr :group_2_attr_2
+
+ define_validator do
+ validates :group_2_attr_1, presence: true
+ validates :group_2_attr_2, presence: true
+ end
+ end
+
+ mattr :group_1_attr
+ end
+end
+```
+
+こんな感じ。
+
+英語がつらいよ。
11 Rakefile
@@ -0,0 +1,11 @@
+require "bundler"
+Bundler.setup
+
+require "rake"
+require "rspec/core/rake_task"
+
+RSpec::Core::RakeTask.new("spec") do |spec|
+ spec.pattern = "spec/**/*_spec.rb"
+end
+
+task :default => :spec
132 lib/mamechiwa.rb
@@ -0,0 +1,132 @@
+require "active_record"
+
+module Mamechiwa
+ module ClassMethods
+ attr_accessor :mame_config, :mame_scope, :mame_group_field
+
+ def mame_config
+ @mame_config ||= Hash.new{ |h,k| h[k] = {} }
+ end
+
+ def mame_scope
+ @mame_scope ||= ""
+ end
+
+ def mamechiwa(field, group_field="")
+ self.mame_group_field = group_field
+
+ yield self
+
+ self.mame_config.each do |k, scope|
+ clazz = create_embedded_class(scope[:attrs])
+ clazz.class_eval &scope[:validator] if scope[:validator]
+
+ scope[:class] = clazz
+ end
+
+ class_eval do
+ define_method :initialize_with_mame do
+ unless @mame_embedded
+ group = self.class.mame_group_field.size > 0 ? self.send(self.class.mame_group_field).to_s : ""
+ @mame_embedded = self.class.mame_config[group][:class].new(self, field)
+ end
+ end
+
+ define_method "#{field}" do
+ initialize_with_mame
+
+ @mame_embedded
+ end
+
+ validate :mame_validator
+
+ define_method :mame_validator do
+ initialize_with_mame
+
+ if !@mame_embedded.valid?
+ @mame_embedded.errors.each do |k, v|
+ errors.add("#{field}[#{k}]", v)
+ end
+ end
+ end
+ end
+ end
+
+ def mattr(*name)
+ mame_config[mame_scope][:attrs] ||= []
+ mame_config[mame_scope][:attrs] += [name].flatten
+ mame_config[mame_scope][:attrs].uniq!
+ end
+
+ def define_validator(&validator)
+ mame_config[mame_scope][:validator] = validator
+ end
+
+ def mame_group(name)
+ self.mame_scope = name
+ yield self
+ self.mame_scope = ""
+ end
+
+ def create_embedded_class(attrs)
+ clazz = Class.new(Hash) do
+ include ActiveModel::Validations
+
+ define_method :mame_attrs do
+ attrs
+ end
+
+ def self.name
+ "mamechiwa_embedded"
+ end
+
+ def initialize(parent, field)
+ @mame_parent = parent
+ @mame_parent_field = field
+
+ value = @mame_parent.send(:[], @mame_parent_field)
+
+ mame_attrs.each do |attr|
+ self[attr.to_s] = nil
+ end
+
+ if value
+ self.merge!(ActiveSupport::JSON.decode(value))
+ end
+ end
+
+ def serialize
+ self.to_json
+ end
+
+ alias :old_get :[]
+
+ def [](arg)
+ self.old_get(arg)
+ end
+
+ alias :old_set :[]=
+
+ def []=(*args)
+ key, value = args
+ self.old_set(key, value)
+ @mame_parent.send(:write_attribute, @mame_parent_field.to_sym, self.serialize)
+ end
+
+ attrs.each do |attr|
+ class_eval <<-EOF
+ def #{attr}
+ self["#{attr}"]
+ end
+
+ def #{attr}=(value)
+ self["#{attr}"] = value
+ end
+ EOF
+ end
+ end
+ end
+ end
+end
+
+require "mamechiwa/integrations/active_record"
7 lib/mamechiwa/integrations/active_record.rb
@@ -0,0 +1,7 @@
+module Mamechiwa
+ module Integrations
+ module ActiveRecord
+ ::ActiveRecord::Base.extend(Mamechiwa::ClassMethods)
+ end
+ end
+end
5 lib/mamechiwa/version.rb
@@ -0,0 +1,5 @@
+module Mamechiwa
+ module Version
+ STRING = "0.0.0"
+ end
+end
20 mamechiwa.gemspec
@@ -0,0 +1,20 @@
+$:.unshift File.expand_path("../lib", __FILE__)
+
+require "mamechiwa/version"
+
+Gem::Specification.new do |s|
+ s.name = "mamechiwa"
+ s.version = Mamechiwa::Version::STRING
+ s.summary = "hanako kawaii"
+ s.description = "Seriarizer to store databae via active record. murina mono ha muri!"
+ s.authors = ["sutetotanuki"]
+ s.email = "sutetotanuki@gmail.com"
+ s.files = Dir["lib/**/*"]
+ s.homepage = "https://github.com/sutetotanuki/mamechiwa"
+
+ s.add_runtime_dependency("activerecord")
+ s.add_runtime_dependency("mysql2")
+ s.add_development_dependency("rspec")
+ s.add_development_dependency("mocha")
+ s.add_development_dependency("database_cleaner")
+end
71 spec/mamechiwa_spec.rb
@@ -0,0 +1,71 @@
+require "spec_helper"
+
+describe Mamechiwa do
+ before { @mame = MamechiwaTest.new }
+
+ it "should set value like hash" do
+ @mame.options.name = "aa"
+ @mame.options["name"].should eq "aa"
+ end
+
+ it "should validation with define validator" do
+ @mame.should_not be_valid
+ end
+
+ it "should set error message when validation is fail" do
+ @mame.valid?
+ @mame.errors["options[name]"].should eq ["can't be blank"]
+ end
+
+ it "should decode from serialized value from database" do
+ @mame.options.name = "hanako"
+ @mame.options.value = "kawaii"
+ @mame.save!
+ @fetched = MamechiwaTest.find(@mame.id)
+ @fetched.options.value.should eq "kawaii"
+ end
+
+ describe "as_json" do
+ it "should include the defined option" do
+ @mame.options.name = "aa"
+ @mame.as_json["mamechiwa_test"]["options"]["name"].should eq "aa"
+ end
+
+ it "should include the defined option if not present" do
+ @mame.as_json["mamechiwa_test"]["options"].keys.include?("name").should be_true
+ @mame.as_json["mamechiwa_test"]["options"]["name"].should be_nil
+ end
+ end
+
+ describe "to_json" do
+ it "should convert a json format string" do
+ @mame.options.name = "abc"
+ ActiveSupport::JSON.decode(@mame.to_json)["mamechiwa_test"]["options"]["name"].should eq "abc"
+ end
+ end
+
+ describe "group" do
+ before { @group = Group.new }
+
+ it "should switch default attributes if not define group key" do
+ @group.options.group_1_attr = "a"
+ @group.options.group_1_attr.should eq "a"
+ end
+
+ it "should switch specified attributes by group key" do
+ @group.group_type = "group1"
+ @group.options.group_1_attr = "a"
+ @group.options.group_1_attr.should eq "a"
+
+ @group2 = Group.new({ group_type: "group2" })
+ @group2.options.group_2_attr_1 = "a"
+ @group2.options.group_2_attr_1.should eq "a"
+ end
+
+ it "should error if use other group attribyte" do
+ expect {
+ @group.options.group_2_attr_1
+ }.should raise_error NoMethodError
+ end
+ end
+end
27 spec/spec_helper.rb
@@ -0,0 +1,27 @@
+ENV["RAILS_ENV"] = "test"
+
+$:.unshift File.expand_path("../lib", __FILE__)
+
+require "mamechiwa"
+require "active_record"
+require "database_cleaner"
+
+ActiveRecord::Base.establish_connection('adapter' => 'mysql2', 'database' => 'mamechiwa_test')
+
+Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each { |f| require f }
+
+CreateMamechiwaTests.down rescue ActiveRecord::StatementInvalid
+CreateMamechiwaTests.up
+
+CreateGroups.down rescue ActiveRecord::StatementInvalid
+CreateGroups.up
+
+RSpec.configure do |config|
+ config.before(:suite) do
+ DatabaseCleaner.strategy = :truncation
+ end
+
+ config.before(:each) do
+ DatabaseCleaner.clean
+ end
+end
12 spec/support/migration/create_groups.rb
@@ -0,0 +1,12 @@
+class CreateGroups < ActiveRecord::Migration
+ def self.up
+ create_table :groups do |t|
+ t.string :group_type
+ t.text :options
+ end
+ end
+
+ def self.down
+ drop_table :groups
+ end
+end
11 spec/support/migration/create_mamechiwa_tests.rb
@@ -0,0 +1,11 @@
+class CreateMamechiwaTests < ActiveRecord::Migration
+ def self.up
+ create_table :mamechiwa_tests do |t|
+ t.text :options
+ end
+ end
+
+ def self.down
+ drop_table :mamechiwa_tests
+ end
+end
23 spec/support/model/group.rb
@@ -0,0 +1,23 @@
+class Group < ActiveRecord::Base
+ mamechiwa :options, :group_type do
+ mame_group "group1" do
+ mattr :group_1_attr
+
+ define_validator do
+ validates :group_1_attr, presence: true
+ end
+ end
+
+ mame_group "group2" do
+ mattr :group_2_attr_1
+ mattr :group_2_attr_2
+
+ define_validator do
+ validates :group_2_attr_1, presence: true
+ validates :group_2_attr_2, presence: true
+ end
+ end
+
+ mattr :group_1_attr
+ end
+end
10 spec/support/model/mamechiwa_test.rb
@@ -0,0 +1,10 @@
+class MamechiwaTest < ActiveRecord::Base
+ mamechiwa :options do
+ mattr :name
+ mattr :value
+
+ define_validator do
+ validates :name, presence: true
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.