bitrix_on_rails 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -1
- data/Gemfile.lock +9 -4
- data/Guardfile +1 -0
- data/README.rdoc +8 -2
- data/VERSION +1 -1
- data/app/models/iblock.rb +1 -42
- data/app/models/iblock_element.rb +21 -45
- data/bitrix_on_rails.gemspec +19 -13
- data/lib/bitrix_on_rails.rb +12 -6
- data/lib/bitrix_on_rails/active_record.rb +19 -11
- data/lib/bitrix_on_rails/configuration.rb +26 -0
- data/lib/bitrix_on_rails/engine.rb +0 -3
- data/lib/bitrix_on_rails/iblock_element.rb +112 -0
- data/lib/bitrix_on_rails/iblock_element_prop_m.rb +1 -27
- data/lib/bitrix_on_rails/iblock_element_prop_s.rb +111 -102
- data/test/factories.rb +105 -0
- data/test/helper.rb +23 -30
- data/test/schema.rb +5 -1158
- data/test/test_active_record.rb +36 -0
- data/test/test_bitrix_on_rails.rb +14 -9
- data/test/test_iblock_element.rb +77 -0
- data/test/test_iblock_element_prop_s.rb +111 -0
- metadata +45 -41
data/Gemfile
CHANGED
@@ -4,10 +4,11 @@ source "http://rubygems.org"
|
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
5
5
|
|
6
6
|
gem 'rails', ">= 3.0"
|
7
|
+
gem 'php_serialize', :git => 'git://github.com/dapi/php_serialize.git'
|
7
8
|
|
8
9
|
# Add dependencies to develop your gem here.
|
9
10
|
# Include everything needed to run rake, tests, features, etc.
|
10
|
-
group :development do
|
11
|
+
group :development, :test do
|
11
12
|
gem "sqlite3"
|
12
13
|
gem "shoulda", ">= 0"
|
13
14
|
gem "bundler", "~> 1.0.0"
|
@@ -15,6 +16,8 @@ group :development do
|
|
15
16
|
gem "rcov", ">= 0"
|
16
17
|
gem "ruby-debug19", :require=>'ruby-debug'
|
17
18
|
|
19
|
+
gem 'factory_girl'
|
20
|
+
|
18
21
|
gem 'test-unit'
|
19
22
|
|
20
23
|
gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
|
data/Gemfile.lock
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/dapi/php_serialize.git
|
3
|
+
revision: e7ebc71561d2210481de52e1227fdb4bdb1a39d6
|
4
|
+
specs:
|
5
|
+
php_serialize (1.2)
|
6
|
+
|
1
7
|
GEM
|
2
8
|
remote: http://rubygems.org/
|
3
9
|
specs:
|
@@ -34,8 +40,8 @@ GEM
|
|
34
40
|
columnize (0.3.4)
|
35
41
|
erubis (2.6.6)
|
36
42
|
abstract (>= 1.0.0)
|
43
|
+
factory_girl (2.0.2)
|
37
44
|
git (1.2.5)
|
38
|
-
growl (1.0.3)
|
39
45
|
guard (0.5.1)
|
40
46
|
thor (~> 0.14.6)
|
41
47
|
guard-test (0.3.0)
|
@@ -75,7 +81,6 @@ GEM
|
|
75
81
|
rdoc (~> 3.4)
|
76
82
|
thor (~> 0.14.4)
|
77
83
|
rake (0.9.2)
|
78
|
-
rb-fsevent (0.4.2)
|
79
84
|
rcov (0.9.9)
|
80
85
|
rdoc (3.9.1)
|
81
86
|
rr (1.0.3)
|
@@ -106,11 +111,11 @@ PLATFORMS
|
|
106
111
|
|
107
112
|
DEPENDENCIES
|
108
113
|
bundler (~> 1.0.0)
|
109
|
-
|
114
|
+
factory_girl
|
110
115
|
guard-test
|
111
116
|
jeweler (~> 1.6.4)
|
117
|
+
php_serialize!
|
112
118
|
rails (>= 3.0)
|
113
|
-
rb-fsevent
|
114
119
|
rcov
|
115
120
|
ruby-debug19
|
116
121
|
shoulda
|
data/Guardfile
CHANGED
data/README.rdoc
CHANGED
@@ -23,6 +23,12 @@ prop_s - для одиночных свойтсв, prop_m - для множес
|
|
23
23
|
|
24
24
|
=== Инфоблоки
|
25
25
|
|
26
|
+
Для создания модели элемента инфоблока:
|
27
|
+
- наследуем модель от IblockElement
|
28
|
+
- в конце файла добавляем BitrixOnRails.send :create_iblock_class, _номер_инфоблока_, _имя_модели_ unless Rails.application.config.cache_classes
|
29
|
+
- в config/initializers/bitrix_on_rails.rb в блок BitrixOnRails.configure добавляем c.infoblock _номер_инфоблока_, :extended_class => _имя_модели_
|
30
|
+
Далее работаем с инфоблоком, как с обычной моделью.
|
31
|
+
|
26
32
|
1. Все модели для таблиц b_iblock_*
|
27
33
|
2. Автоматическая установка свойств из таблиц prop_s*/prop_m* в методы объекта IblockElement.
|
28
34
|
Например IblockElement.find(1).name_emittents, где name_emittent - свойство из prop_s.
|
@@ -112,13 +118,13 @@ prop_s - для одиночных свойтсв, prop_m - для множес
|
|
112
118
|
encoding: cp1251
|
113
119
|
...
|
114
120
|
|
115
|
-
==
|
121
|
+
== Тесты
|
116
122
|
|
117
123
|
bundle exec guard
|
118
124
|
|
119
125
|
или
|
120
126
|
|
121
|
-
rake test
|
127
|
+
bundle exec rake test
|
122
128
|
|
123
129
|
== TODO
|
124
130
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/app/models/iblock.rb
CHANGED
@@ -84,21 +84,10 @@ class Iblock < ActiveRecord::Base
|
|
84
84
|
scope.send eval_method, "def #{code}=(value); property_set.send('#{code}=', value); end"
|
85
85
|
end
|
86
86
|
scope.send eval_method, "def property_#{code}=(value); property_set.send('#{code}=', value); end"
|
87
|
-
|
88
|
-
# Если мы спрашиваем iblock_element.post
|
89
|
-
# то он ищет ключ :post_id в свойствах элемента
|
90
|
-
# и если находит, то возвращает Post.find_by_id(properties[:post_id])
|
91
|
-
# if code.to_s=~/_id$/
|
92
|
-
# method = code.to_s.gsub(/_id$/,'')
|
93
|
-
# if Kernel.const_defined? class_name = code.to_s.humanize
|
94
|
-
# instance_eval "def #{method}; #{class_name}.find_by_id(self.send :#{code}); end"
|
95
|
-
# end
|
96
|
-
# end
|
97
87
|
}
|
98
88
|
|
99
89
|
end
|
100
|
-
|
101
|
-
end
|
90
|
+
end # self
|
102
91
|
|
103
92
|
def to_s
|
104
93
|
name
|
@@ -111,34 +100,4 @@ class Iblock < ActiveRecord::Base
|
|
111
100
|
def property_codes
|
112
101
|
self.class.get_property_codes(id)
|
113
102
|
end
|
114
|
-
|
115
|
-
def init_property_models
|
116
|
-
return unless version==2
|
117
|
-
iblock_id = self.id
|
118
|
-
|
119
|
-
# Создаем классы IblockElementPropSНОМЕР
|
120
|
-
#
|
121
|
-
const_name = "IblockElementPropS#{iblock_id}"
|
122
|
-
unless Kernel.const_defined? const_name
|
123
|
-
e = Class.new(ActiveRecord::Base) do
|
124
|
-
extend BitrixOnRails::IblockElementPropS
|
125
|
-
acts_as_iblock_element_prop_s(iblock_id)
|
126
|
-
end
|
127
|
-
Kernel.const_set const_name, e
|
128
|
-
end
|
129
|
-
Kernel.const_get(const_name).init
|
130
|
-
|
131
|
-
# Создаем классы IblockElementPropMНОМЕР
|
132
|
-
#
|
133
|
-
const_name = "IblockElementPropM#{iblock_id}"
|
134
|
-
unless Kernel.const_defined? const_name
|
135
|
-
e = Class.new(ActiveRecord::Base) do
|
136
|
-
extend BitrixOnRails::IblockElementPropM
|
137
|
-
acts_as_iblock_element_prop_m(iblock_id)
|
138
|
-
end
|
139
|
-
Kernel.const_set "IblockElementPropM#{iblock_id}", e
|
140
|
-
end
|
141
|
-
Kernel.const_get(const_name).init
|
142
|
-
end
|
143
|
-
|
144
103
|
end
|
@@ -1,11 +1,30 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
class IblockElement < ActiveRecord::Base
|
3
|
+
|
4
|
+
class << self
|
5
|
+
# Хранит id инфоблока, с которым связан класс. Устанавливается для классов
|
6
|
+
# наследуемых от IblockElement.
|
7
|
+
@iblock_id = nil
|
8
|
+
|
9
|
+
# Хранит хеш свойств, хранящихся в IblockElementPropS*. Устанавливается для
|
10
|
+
# классов наследуемых от IblockElement.
|
11
|
+
@iblock_properties = nil
|
12
|
+
|
13
|
+
def iblock_id
|
14
|
+
@iblock_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def iblock_properties
|
18
|
+
@iblock_properties
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
3
22
|
set_table_name :b_iblock_element
|
4
23
|
|
5
24
|
belongs_to :iblock
|
6
25
|
belongs_to :iblock_section
|
7
26
|
|
8
|
-
after_find { Iblock.define_delegated_methods(self, self.iblock_id) }
|
27
|
+
# after_find { Iblock.define_delegated_methods(self, self.iblock_id) }
|
9
28
|
|
10
29
|
# Применяется только для iblock-ов 1-й версии
|
11
30
|
#
|
@@ -16,42 +35,7 @@ class IblockElement < ActiveRecord::Base
|
|
16
35
|
has_many :iblock_section_elements
|
17
36
|
has_many :iblock_sections, :through => :iblock_section_elements
|
18
37
|
|
19
|
-
|
20
|
-
def iblock_id
|
21
|
-
@iblock_id
|
22
|
-
end
|
23
|
-
|
24
|
-
def property_codes
|
25
|
-
raise "Не установлен @iblock_id" unless iblock_id
|
26
|
-
Iblock.get_property_codes(iblock_id)
|
27
|
-
end
|
28
|
-
|
29
|
-
def set_iblock_id(id)
|
30
|
-
@iblock_id = id
|
31
|
-
|
32
|
-
hash = {
|
33
|
-
:class_name => Iblock.s_props_class(id).name,
|
34
|
-
:foreign_key => 'iblock_element_id',
|
35
|
-
:autosave => true}
|
36
|
-
has_one :s_prop, hash
|
37
|
-
has_one "iblock_element_prop_s#{iblock_id}".to_sym, hash
|
38
|
-
|
39
|
-
has_many :m_prop_values, :class_name => Iblock.m_props_class(id),
|
40
|
-
:foreign_key => 'iblock_element_id', :autosave => true
|
41
|
-
|
42
|
-
default_scope where(:iblock_id => id, :active => 'Y')
|
43
|
-
|
44
|
-
property_codes.each { |code, number|
|
45
|
-
define_method(code) do
|
46
|
-
property_set.send(code)
|
47
|
-
end
|
48
|
-
|
49
|
-
define_method("#{code}=") do |value|
|
50
|
-
property_set.send("#{code}=", value)
|
51
|
-
end
|
52
|
-
}
|
53
|
-
end
|
54
|
-
end
|
38
|
+
default_scope where(:active => 'Y')
|
55
39
|
|
56
40
|
def property_codes
|
57
41
|
::Iblock.get_property_codes(self.iblock_id)
|
@@ -60,12 +44,4 @@ class IblockElement < ActiveRecord::Base
|
|
60
44
|
def to_s
|
61
45
|
name
|
62
46
|
end
|
63
|
-
|
64
|
-
def multiply_properties
|
65
|
-
send "iblock_element_prop_m#{iblock_id}"
|
66
|
-
end
|
67
|
-
|
68
|
-
def property_set
|
69
|
-
send "iblock_element_prop_s#{iblock_id}"
|
70
|
-
end
|
71
47
|
end
|
data/bitrix_on_rails.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bitrix_on_rails}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{2011-08-
|
11
|
+
s.authors = [%q{Danil Pismenny}]
|
12
|
+
s.date = %q{2011-08-29}
|
13
13
|
s.description = %q{Использование инфоблоков 1С-Битрикс в Ruby On Rails проектах}
|
14
14
|
s.email = %q{danil@orionet.ru}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -40,19 +40,25 @@ Gem::Specification.new do |s|
|
|
40
40
|
"lib/active_record/connection_adapters/mysql2_downcase_adapter.rb",
|
41
41
|
"lib/bitrix_on_rails.rb",
|
42
42
|
"lib/bitrix_on_rails/active_record.rb",
|
43
|
+
"lib/bitrix_on_rails/configuration.rb",
|
43
44
|
"lib/bitrix_on_rails/engine.rb",
|
45
|
+
"lib/bitrix_on_rails/iblock_element.rb",
|
44
46
|
"lib/bitrix_on_rails/iblock_element_prop_m.rb",
|
45
47
|
"lib/bitrix_on_rails/iblock_element_prop_s.rb",
|
46
48
|
"test/dump.sql",
|
49
|
+
"test/factories.rb",
|
47
50
|
"test/get_dump.sh",
|
48
51
|
"test/helper.rb",
|
49
52
|
"test/schema.rb",
|
50
|
-
"test/
|
53
|
+
"test/test_active_record.rb",
|
54
|
+
"test/test_bitrix_on_rails.rb",
|
55
|
+
"test/test_iblock_element.rb",
|
56
|
+
"test/test_iblock_element_prop_s.rb"
|
51
57
|
]
|
52
58
|
s.homepage = %q{http://github.com/dapi/bitrix_on_rails}
|
53
|
-
s.licenses = [
|
54
|
-
s.require_paths = [
|
55
|
-
s.rubygems_version = %q{1.6
|
59
|
+
s.licenses = [%q{MIT}]
|
60
|
+
s.require_paths = [%q{lib}]
|
61
|
+
s.rubygems_version = %q{1.8.6}
|
56
62
|
s.summary = %q{Работа с инфоблоками 1С-Битрикс}
|
57
63
|
|
58
64
|
if s.respond_to? :specification_version then
|
@@ -60,42 +66,42 @@ Gem::Specification.new do |s|
|
|
60
66
|
|
61
67
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
62
68
|
s.add_runtime_dependency(%q<rails>, [">= 3.0"])
|
69
|
+
s.add_runtime_dependency(%q<php_serialize>, [">= 0"])
|
63
70
|
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
64
71
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
65
72
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
66
73
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
67
74
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
68
75
|
s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
|
76
|
+
s.add_development_dependency(%q<factory_girl>, [">= 0"])
|
69
77
|
s.add_development_dependency(%q<test-unit>, [">= 0"])
|
70
|
-
s.add_development_dependency(%q<rb-fsevent>, [">= 0"])
|
71
|
-
s.add_development_dependency(%q<growl>, [">= 0"])
|
72
78
|
s.add_development_dependency(%q<guard-test>, [">= 0"])
|
73
79
|
s.add_development_dependency(%q<test-unit-rr>, [">= 0"])
|
74
80
|
else
|
75
81
|
s.add_dependency(%q<rails>, [">= 3.0"])
|
82
|
+
s.add_dependency(%q<php_serialize>, [">= 0"])
|
76
83
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
77
84
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
78
85
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
79
86
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
80
87
|
s.add_dependency(%q<rcov>, [">= 0"])
|
81
88
|
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
89
|
+
s.add_dependency(%q<factory_girl>, [">= 0"])
|
82
90
|
s.add_dependency(%q<test-unit>, [">= 0"])
|
83
|
-
s.add_dependency(%q<rb-fsevent>, [">= 0"])
|
84
|
-
s.add_dependency(%q<growl>, [">= 0"])
|
85
91
|
s.add_dependency(%q<guard-test>, [">= 0"])
|
86
92
|
s.add_dependency(%q<test-unit-rr>, [">= 0"])
|
87
93
|
end
|
88
94
|
else
|
89
95
|
s.add_dependency(%q<rails>, [">= 3.0"])
|
96
|
+
s.add_dependency(%q<php_serialize>, [">= 0"])
|
90
97
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
91
98
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
92
99
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
93
100
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
94
101
|
s.add_dependency(%q<rcov>, [">= 0"])
|
95
102
|
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
103
|
+
s.add_dependency(%q<factory_girl>, [">= 0"])
|
96
104
|
s.add_dependency(%q<test-unit>, [">= 0"])
|
97
|
-
s.add_dependency(%q<rb-fsevent>, [">= 0"])
|
98
|
-
s.add_dependency(%q<growl>, [">= 0"])
|
99
105
|
s.add_dependency(%q<guard-test>, [">= 0"])
|
100
106
|
s.add_dependency(%q<test-unit-rr>, [">= 0"])
|
101
107
|
end
|
data/lib/bitrix_on_rails.rb
CHANGED
@@ -1,19 +1,25 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'rails'
|
3
3
|
require 'active_record'
|
4
|
+
require 'php_serialize'
|
4
5
|
|
5
6
|
module BitrixOnRails
|
6
|
-
def self.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
def self.configure
|
8
|
+
return unless ::ActiveRecord::Base.connection.tables.include? 'b_iblock'
|
9
|
+
|
10
|
+
config = Configuration.new
|
11
|
+
yield config
|
12
|
+
|
13
|
+
config.infoblocks.each { |infoblock|
|
14
|
+
BitrixOnRails.define_iblock_class(infoblock[:iblock_id], infoblock[:options])
|
15
|
+
}
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
15
19
|
require 'bitrix_on_rails/engine'
|
20
|
+
require 'bitrix_on_rails/configuration'
|
16
21
|
require 'bitrix_on_rails/active_record'
|
22
|
+
require 'bitrix_on_rails/iblock_element'
|
17
23
|
require 'bitrix_on_rails/iblock_element_prop_s'
|
18
24
|
require 'bitrix_on_rails/iblock_element_prop_m'
|
19
25
|
|
@@ -3,22 +3,30 @@
|
|
3
3
|
module BitrixOnRails
|
4
4
|
module ActiveRecord
|
5
5
|
|
6
|
-
|
6
|
+
# TODO: Добавить еще один параметр delegated_methods, через который пользователь сможет определить
|
7
|
+
# методы, которые необходимо проделегировать в iblock_element
|
8
|
+
def has_infoblock(iblock_id, foreign_key)
|
7
9
|
prop_s_name = "iblock_element_prop_s#{iblock_id}".to_sym
|
8
|
-
|
10
|
+
iblock_element_class = BitrixOnRails.infoblocks[iblock_id]
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
element_class.class_eval(&blk) if block_given?
|
12
|
+
has_one prop_s_name, :class_name => "::IblockElementPropS#{iblock_id}", :foreign_key => foreign_key , :autosave => true
|
13
|
+
full_class_name = self.name
|
14
|
+
class_name = full_class_name.split('::').last.underscore.to_sym
|
14
15
|
|
15
|
-
|
16
|
+
Object.const_get("IblockElementPropS#{iblock_id}").instance_eval {
|
17
|
+
belongs_to class_name, :class_name => full_class_name, :foreign_key => foreign_key
|
18
|
+
}
|
16
19
|
|
17
|
-
|
18
|
-
Iblock.define_delegated_methods(self, iblock_id, true)
|
19
|
-
|
20
|
-
has_one :iblock_element, :through => prop_s_name, :class_name => 'Element', :autosave => true
|
20
|
+
has_one :iblock_element, :class_name => iblock_element_class.name, :through => prop_s_name
|
21
21
|
|
22
|
+
iblock_element_class.iblock_properties.each { |m, property|
|
23
|
+
# Во избежание коллизий не стоит делегировать методы вроде post_id, blog_id дальше
|
24
|
+
unless m.to_s =~ /_id$/ || self.columns.find{ |c| c.name == m.to_s}
|
25
|
+
delegate m, :to => :iblock_element
|
26
|
+
delegate "#{m}=", :to => :iblock_element unless property[:multiple]
|
27
|
+
end
|
28
|
+
}
|
22
29
|
end
|
30
|
+
|
23
31
|
end
|
24
32
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module BitrixOnRails
|
2
|
+
class Configuration
|
3
|
+
attr_reader :infoblocks
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@infoblocks = []
|
7
|
+
end
|
8
|
+
|
9
|
+
# Создание необходимой инфраструктуры для работы с инфоблоком, id которого равен iblock_id.
|
10
|
+
# Пользователь может задать следующие параметры через options:
|
11
|
+
#
|
12
|
+
# * :class_name - имя класса для создаваемого наследника от IblockElement. Если пользователь не задал
|
13
|
+
# эту опцию, а также не задал :extended_class, то новый класс будет называется IblockElement3, где 3 -
|
14
|
+
# iblock_id.
|
15
|
+
# * :extended_class - класс, который необходимо расширить (предполагается, что он наследуется от IblockElement).
|
16
|
+
# Эта опция имеет преимущество перед :class_name.
|
17
|
+
# * :extended_by - модуль, который будет включен в создаваемый класс.
|
18
|
+
#
|
19
|
+
def infoblock(iblock_id, options = {})
|
20
|
+
@infoblocks << {
|
21
|
+
:iblock_id => iblock_id,
|
22
|
+
:options => options
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|