belongs_to association for content entries [WIP]

did committed Mar 01, 2015
commit d9582c9f299d93ce6bc024c4c7c4d47ba02fc0b2
Showing 25 changed files with 537 additions and 432 deletions
locomotive/steam/adapters/filesystem.rb b/lib/locomotive/steam/adapters/filesystem.rb +11 -1
@@ @@ -35,7 +35,8 @@ module Locomotive::Steam
end
def find(mapper, scope, id)
- _query(mapper, scope) { where(_id: id) }.first
+ name = identifier_name(mapper)
+ _query(mapper, scope) { where(name => id) }.first
end
def theme_assets_base_url(scope)
@@ @@ -44,6 +45,15 @@ module Locomotive::Steam
private
+ def identifier_name(mapper)
+ case mapper.name
+ when :content_types then :slug
+ when :content_entries then :_slug
+ else
+ :_id
+ end
+ end
+
def _query(mapper, scope, &block)
Locomotive::Steam::Adapters::Memory::Query.new(all(mapper, scope), scope.locale, &block)
end
locomotive/steam/adapters/filesystem/sanitizers/content_entry.rb b/lib/locomotive/steam/adapters/filesystem/sanitizers/content_entry.rb +1 -76
@@ @@ -33,12 +33,11 @@ module Locomotive::Steam
def set_slug(entry, dataset)
if entry._label.respond_to?(:translations) # localized?
- entry[:_slug] ||= {}
entry._label.each do |locale, label|
entry[:_slug][locale] ||= slugify(label, dataset, locale)
end
else
- entry[:_slug] ||= slugify(entry._label, dataset)
+ entry[:_slug][locale] = slugify(entry._label, dataset)
end
end
@@ @@ -55,9 +54,6 @@ module Locomotive::Steam
def is_slug_unique?(slug, dataset, locale)
dataset.query(locale) { where(_slug: slug) }.first.nil?
- # Filesystem::MemoryAdapter::Query.new(collection, locale) do
- # where(_slug: slug)
- # end.first.nil?
end
end
@@ @@ -66,74 +62,3 @@ module Locomotive::Steam
end
end
end
-
-
-
-
-
- # module Locomotive
- # module Steam
- # module Repositories
- # module Filesystem
- # module Sanitizers
-
- # class ContentEntry < Struct.new(:default_locale, :locales)
-
- # def apply_to(collection)
- # collection.each do |entry|
- # set_content_type(entry)
- # add_label(entry)
- # set_slug(entry, collection)
- # end
- # end
-
- # def set_slug(entry, collection)
- # if entry._label.is_a?(Hash)
- # entry[:_slug] ||= {}
- # entry._label.each do |locale, label|
- # entry[:_slug][locale] ||= slugify(label, collection, locale)
- # end
- # else
- # entry[:_slug] ||= slugify(entry._label, collection)
- # end
- # end
-
- # def slugify(label, collection, locale = nil)
- # base, index = label.permalink(false), nil
- # _slugify = -> (i) { [base, i].compact.join('-') }
-
- # while !is_slug_unique?(_slugify.call(index), collection, locale)
- # index = index ? index + 1 : 1
- # end
-
- # _slugify.call(index)
- # end
-
- # def is_slug_unique?(slug, collection, locale)
- # Filesystem::MemoryAdapter::Query.new(collection, locale) do
- # where(_slug: slug)
- # end.first.nil?
- # end
-
- # def set_content_type(entry)
- # entry.content_type = entry.attributes.delete(:content_type)
- # end
-
- # def add_label(entry)
- # value = entry.attributes.delete(:_label)
- # name = entry.content_type.label_field_name
-
- # if entry.attributes[name].is_a?(Hash) # localized?
- # entry.attributes[name][default_locale] = value
- # else
- # entry.attributes[name] ||= value
- # end
- # end
-
- # end
-
- # end
- # end
- # end
- # end
- # end
locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb b/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb +20 -3
@@ @@ -18,12 +18,25 @@ module Locomotive
def load_list
[].tap do |list|
each(content_type_slug) do |label, attributes, position|
- default = { _position: position, _label: label.to_s }
- list << default.merge(attributes)
+ _attributes = { _position: position, _label: label.to_s }.merge(attributes)
+
+ setup_belongs_to_associations(_attributes)
+
+ list << _attributes
end
end
end
+ def setup_belongs_to_associations(attributes)
+ content_type.belongs_to_fields.each do |field|
+ # <name>_id
+ attributes[:"#{field.name}_id"] = attributes.delete(field.name.to_sym)
+
+ # _position_in_<name>
+ attributes[:"_position_in_#{field.name}"] = attributes[:_position]
+ end
+ end
+
def each(slug, &block)
position = 0
_load(File.join(path, "#{slug}.yml")).each do |element|
@@ @@ -37,8 +50,12 @@ module Locomotive
File.join(site_path, 'data')
end
+ def content_type
+ @scope.context[:content_type]
+ end
+
def content_type_slug
- @scope.context[:content_type].slug
+ content_type.slug
end
end
locomotive/steam/entities/content_entry.rb b/lib/locomotive/steam/entities/content_entry.rb +10 -14
@@ @@ -4,7 +4,7 @@ module Locomotive::Steam
class ContentEntry
- ASSOCIATION_NAMES = [:belongs_to, :has_many, :many_to_many].freeze
+ # ASSOCIATION_NAMES = [:belongs_to, :has_many, :many_to_many].freeze
include Locomotive::Steam::Models::Entity
@@ @@ -55,10 +55,6 @@ module Locomotive::Steam
self[content_type.label_field_name]
end
- # def localized_attributes
- # self.class.localized_attributes + content_type.localized_fields_names
- # end
-
def to_liquid
Locomotive::Steam::Liquid::Drops::ContentEntry.new(self)
end
@@ @@ -81,9 +77,9 @@ module Locomotive::Steam
end
def _cast_value(field)
- if ASSOCIATION_NAMES.include?(field.type)
- AssociationMetadata.new(field.type, self, field, [*attributes[field.name]])
- elsif private_methods.include?(:"_cast_#{field.type}")
+ # if ASSOCIATION_NAMES.include?(field.type)
+ # AssociationMetadata.new(field.type, self, field, [*attributes[field.name]])
+ if private_methods.include?(:"_cast_#{field.type}")
send(:"_cast_#{field.type}", field.name)
else
attributes[field.name]
@@ @@ -127,12 +123,12 @@ module Locomotive::Steam
end
end
- class AssociationMetadata < Struct.new(:type, :source, :field, :target_slugs)
- def association; true; end
- def inverse_of; field.inverse_of; end
- def target_class_slug; field.class_name; end
- def order_by; field[:order_by]; end
- end
+ # class AssociationMetadata < Struct.new(:type, :source, :field, :target_slugs)
+ # def association; true; end
+ # def inverse_of; field.inverse_of; end
+ # def target_class_slug; field.class_name; end
+ # def order_by; field[:order_by]; end
+ # end
end
locomotive/steam/entities/content_type.rb b/lib/locomotive/steam/entities/content_type.rb +10 -3
@@ @@ -3,6 +3,9 @@ module Locomotive::Steam
class ContentType
include Locomotive::Steam::Models::Entity
+ extend Forwardable
+
+ def_delegators :fields, :localized_fields_names, :belongs_to_fields
def initialize(attributes = {})
super({
@@ @@ -23,9 +26,13 @@ module Locomotive::Steam
end)
end
- def localized_fields_names
- self.fields.localized_fields_names
- end
+ # def belongs_to_fields
+ # self.fields.belongs_to
+ # end
+
+ # def localized_fields_names
+ # self.fields.localized_fields_names
+ # end
def label_field_name
(self[:label_field_name] || fields.first.name).to_sym
locomotive/steam/entities/content_type_field.rb b/lib/locomotive/steam/entities/content_type_field.rb +10 -0
@@ @@ -15,13 +15,23 @@ module Locomotive::Steam
}.merge(attributes))
end
+ def type
+ self[:type].try(:to_sym)
+ end
+
def class_name
self[:class_name] || self[:target]
end
+ alias :target :class_name
+
def required?; self[:required]; end
def localized?; self[:localized]; end
+ def association_options
+ @attributes.slice(:inverse_of, :order_by).merge(class_name: class_name)
+ end
+
class SelectOption
include Locomotive::Steam::Models::Entity
locomotive/steam/liquid/drops/content_types.rb b/lib/locomotive/steam/liquid/drops/content_types.rb +1 -0
@@ @@ -58,6 +58,7 @@ module Locomotive
end
def collection
+ # TODO: repository.for(@content_type).all(....)
@collection ||= repository.all(@content_type, @context['with_scope'])
end
locomotive/steam/models.rb b/lib/locomotive/steam/models.rb +2 -1
@@ @@ -1,6 +1,7 @@
require_relative 'models/concerns/validation'
require_relative 'models/i18n_field'
- require_relative 'models/association'
+ require_relative 'models/associations/embedded'
+ require_relative 'models/associations/belongs_to'
require_relative 'models/entity'
require_relative 'models/mapper'
require_relative 'models/scope'
locomotive/steam/models/association.rb b/lib/locomotive/steam/models/association.rb +0 -40
@@ @@ -1,40 +0,0 @@
- require 'locomotive/steam/adapters/memory'
- require 'morphine'
-
- module Locomotive::Steam
- module Models
-
- # Note: represents an embedded collection
- class Association
-
- include Morphine
-
- register :adapter do
- Locomotive::Steam::MemoryAdapter.new(nil)
- end
-
- # use the scope from the parent repository
- # one of the benefits is that if we change the current_locale
- # of the parent repository, that will change the local repository
- # as well.
- def initialize(repository_klass, collection, scope)
- adapter.collection = collection
-
- @repository = repository_klass.new(adapter)
- @repository.scope = scope
- end
-
- # In order to keep track of the entity which owns
- # the association.
- def attach(name, entity)
- @repository.send(:"#{name}=", entity)
- end
-
- def method_missing(name, *args, &block)
- @repository.send(name, *args, &block)
- end
-
- end
-
- end
- end
locomotive/steam/models/associations/belongs_to.rb b/lib/locomotive/steam/models/associations/belongs_to.rb +41 -0
@@ @@ -0,0 +1,41 @@
+ require 'locomotive/steam/adapters/memory'
+ require 'morphine'
+
+ module Locomotive::Steam
+ module Models
+
+ # Note: represents an embedded collection
+ class BelongsToAssociation
+
+ attr_reader :repository
+
+ def initialize(repository_klass, scope, adapter)
+ # build a new instance of the target repository
+ @repository = repository_klass.new(adapter)
+
+ # Note: if we change the locale of the parent repository, that won't
+ # reflect in that repository
+ @repository.scope = scope.dup
+ end
+
+ def attach(name, entity)
+ @name, @entity = name, entity
+ end
+
+ def target_id
+ @entity[:"#{@name}_id"]
+ end
+
+ def method_missing(name, *args, &block)
+ target = @repository.find(target_id)
+
+ # replace the proxy class by the real target entity
+ @entity[@name] = target
+
+ target.try(:send, name, *args, &block)
+ end
+
+ end
+
+ end
+ end
locomotive/steam/models/associations/embedded.rb b/lib/locomotive/steam/models/associations/embedded.rb +40 -0
@@ @@ -0,0 +1,40 @@
+ require 'locomotive/steam/adapters/memory'
+ require 'morphine'
+
+ module Locomotive::Steam
+ module Models
+
+ # Note: represents an embedded collection
+ class EmbeddedAssociation
+
+ include Morphine
+
+ register :adapter do
+ Locomotive::Steam::MemoryAdapter.new(nil)
+ end
+
+ # use the scope from the parent repository
+ # one of the benefits is that if we change the current_locale
+ # of the parent repository, that will change the local repository
+ # as well.
+ def initialize(repository_klass, collection, scope)
+ adapter.collection = collection
+
+ @repository = repository_klass.new(adapter)
+ @repository.scope = scope
+ end
+
+ # In order to keep track of the entity which owns
+ # the association.
+ def attach(name, entity)
+ @repository.send(:"#{name}=", entity)
+ end
+
+ def method_missing(name, *args, &block)
+ @repository.send(name, *args, &block)
+ end
+
+ end
+
+ end
+ end
locomotive/steam/models/associations/has_many.rb b/lib/locomotive/steam/models/associations/has_many.rb +52 -0
@@ @@ -0,0 +1,52 @@
+ require 'locomotive/steam/adapters/memory'
+ require 'morphine'
+
+ module Locomotive::Steam
+ module Models
+
+ # Note: represents an embedded collection
+ class HasManyAssociation
+
+ attr_reader :repository
+
+ def initialize(repository_klass, scope, adapter)
+ @repository = repository_klass.new(adapter)
+
+ # Note: if we change the locale of the parent repository, that won't
+ # reflect in that repository
+ @repository.scope = scope.dup
+ end
+
+ def set_condition
+ @repository.association_condition = { }
+ end
+
+ def method_missing(name, *args, &block)
+ @repository.send(name, *args, &block)
+ end
+
+ # include Morphine
+
+ # # use the scope from the parent repository
+ # # one of the benefits is that if we change the current_locale
+ # # of the parent repository, that will change the local repository
+ # # as well.
+ # def initialize(repository_klass, collection, scope)
+ # adapter.collection = collection
+
+ # @repository = repository_klass.new(adapter)
+ # @repository.scope = scope
+ # end
+
+ # # In order to keep track of the entity which owns
+ # # the association.
+ # def attach(name, entity)
+ # @repository.send(:"#{name}=", entity)
+ # end
+
+
+
+ end
+
+ end
+ end
locomotive/steam/models/i18n_field.rb b/lib/locomotive/steam/models/i18n_field.rb +4 -4
@@ @@ -8,11 +8,11 @@ module Locomotive::Steam
def initialize(name, translations)
@name = name
- if translations.respond_to?(:fetch)
- @translations = translations.with_indifferent_access
+ @translations = (if translations.respond_to?(:fetch)
+ translations
else
- @translations = Hash.new { translations }
- end
+ Hash.new { translations }
+ end).with_indifferent_access
end
def [](locale)
locomotive/steam/models/mapper.rb b/lib/locomotive/steam/models/mapper.rb +35 -12
@@ @@ -10,7 +10,7 @@ module Locomotive::Steam
@localized_attributes = []
@default_attributes = []
- @associations = []
+ @associations = { embedded: [], belongs_to: [] }
instance_eval(&block) if block_given?
end
@@ @@ -23,14 +23,18 @@ module Locomotive::Steam
@default_attributes += [[name.to_sym, value]]
end
- # Note: only works for embedded-type associations
- def association(name, repository_klass)
- @associations += [[name.to_sym, repository_klass]]
+ def belongs_to_association(name, repository_klass, options = {})
+ @associations[:belongs_to] += [[name.to_sym, repository_klass, options]]
+ end
+
+ def embedded_association(name, repository_klass)
+ @associations[:embedded] += [[name.to_sym, repository_klass]]
end
def to_entity(attributes)
entity_klass.new(serialize(attributes)).tap do |entity|
- attach_entity_to_associations(entity)
+ attach_entity_to_embedded_associations(entity)
+ attach_entity_to_belongs_to_associations(entity)
set_default_attributes(entity)
end
end
@@ @@ -38,7 +42,8 @@ module Locomotive::Steam
def serialize(attributes)
serialize_localized_attributes(attributes)
- serialize_associations(attributes)
+ serialize_embedded_associations(attributes)
+ serialize_belongs_to_associations(attributes)
attributes
end
@@ @@ -47,6 +52,11 @@ module Locomotive::Steam
options[:entity]
end
+ def i18n_value_of(entity, name, locale)
+ value = entity.send(name.to_sym)
+ value.respond_to?(:translations) ? value[locale] : value
+ end
+
private
# create a proxy class for each localized attribute
@@ @@ -57,16 +67,29 @@ module Locomotive::Steam
end
# build the embedded associations
- def serialize_associations(attributes)
- @associations.each do |name, repository_klass|
- attributes[name] = Association.new(repository_klass, attributes[name], @repository.scope)
+ def serialize_embedded_associations(attributes)
+ @associations[:embedded].each do |name, repository_klass|
+ attributes[name] = EmbeddedAssociation.new(repository_klass, attributes[name], @repository.scope)
+ end
+ end
+
+ # build the belongs_to associations
+ def serialize_belongs_to_associations(attributes)
+ @associations[:belongs_to].each do |name, repository_klass, options|
+ attributes[name] = BelongsToAssociation.new(repository_klass, @repository.scope, @repository.adapter)
end
end
- def attach_entity_to_associations(entity)
- @associations.each do |(name, _)|
+ def attach_entity_to_embedded_associations(entity)
+ @associations[:embedded].each do |(name, _)|
key = self.name.to_s.singularize.to_sym
- entity[name].attach(key, entity)
+ entity[name].attach(key, entity) # Note: entity[name] is a proxy class
+ end
+ end
+
+ def attach_entity_to_belongs_to_associations(entity)
+ @associations[:belongs_to].each do |(name, _)|
+ entity[name].attach(name, entity) # Note: entity[name] is a proxy class
end
end
locomotive/steam/models/repository.rb b/lib/locomotive/steam/models/repository.rb +12 -0
@@ @@ -17,6 +17,14 @@ module Locomotive::Steam
@scope = Scope.new(site, locale)
end
+ def build(attributes, &block)
+ mapper.to_entity(attributes)
+ end
+
+ def create(entity)
+ adapter.create(entity)
+ end
+
def find(id)
adapter.find(mapper, scope, id)
end
@@ @@ -43,6 +51,10 @@ module Locomotive::Steam
@mapper = Mapper.new(name, options, self, &block)
end
+ def i18n_value_of(entity, name)
+ mapper.i18n_value_of(entity, name, locale)
+ end
+
# TODO: not sure about that. could it be used further in the dev
# def collection_name
# mapper.name
locomotive/steam/repositories/content_entry_repository.rb b/lib/locomotive/steam/repositories/content_entry_repository.rb +76 -113
@@ @@ -5,9 +5,11 @@ module Locomotive
include Models::Repository
- attr_accessor :content_type
+ attr_reader :content_type_repository
+ attr_accessor :content_type, :local_conditions
def initialize(adapter, site = nil, locale = nil, content_type_repository = nil)
+ @local_conditions = {}
@adapter = adapter
@scope = Locomotive::Steam::Models::Scope.new(site, locale)
@content_type_repository = content_type_repository
@@ @@ -18,94 +20,53 @@ module Locomotive
localized_attributes :_slug, :seo_title, :meta_description, :meta_keywords
default_attribute :content_type, -> (repository) { repository.content_type }
-
- # # embedded association
- # association :entries_custom_fields, ContentTypeFieldRepository
end
- def all(type, conditions = {})
- conditions = { _visible: true }.merge(conditions || {})
-
+ # this is the starting point of all the next actions
+ def with(type)
self.content_type = type # used for creating the scope
self.scope.context[:content_type] = type
- # filter the entries by the content type they belong to
- conditions[:content_type_id] = type._id
+ @local_conditions[:content_type_id] = type.try(:_id)
+
+ self # chainable
+ end
+
+ def all(conditions = {})
+ conditions = prepare_conditions({ _visible: true }, conditions)
# priority:
# 1/ order_by passed in the conditions parameter
# 2/ the default order (_position) defined in the content type
- order_by = conditions.delete(:order_by)|| conditions.delete('order_by') || type.order_by
+ order_by = conditions.delete(:order_by)|| conditions.delete('order_by') || content_type.order_by
query { where(conditions).order_by(order_by) }.all
end
- # Engine: content_type.entries.build(attributes)
- def build(type, attributes = {})
- raise 'TODO, delegate to the adapter'
-
- # collection_options[:model].new(attributes).tap do |entry|
- # # set the reference to the content type
- # entry.content_type = type
- # end
+ def exists?(conditions = {})
+ conditions = prepare_conditions(conditions)
+ query { where(conditions) }.all.size > 0
end
- # Engine: entry.save
- def persist(entry)
- return nil if entry.nil?
-
- raise 'TODO, delegate to the adapter'
-
- # collection = memoized_collection(entry.content_type)
-
- # # slugify entry
- # sanitizer.set_slug(entry, collection)
-
- # collection << entry # immediate result
-
- # # make sure we write it back to the data source
- # loader.write(entry.content_type, entry.attributes)
- end
-
- # Engine: all(conditions).count > 0
- def exists?(type, conditions = {})
- query(type) { where(conditions) }.all.size > 0
- end
-
- # Engine: not necessary
- def by_slug(type, slug)
- query(type) { where(_slug: slug) }.first
+ def by_slug(slug)
+ conditions = prepare_conditions(_slug: slug)
+ first { where(conditions) }
end
- # Engine: entry.send(:name) :-)
- def value_for(name, entry, conditions = {})
- value = entry.send(name)
-
- if value.respond_to?(:association)
- association(value, conditions || {})
- else
- value
- end
- end
-
- # Engine: entry.next
def next(entry)
next_or_previous(entry, 'gt', 'lt')
end
- # Engine: entry.previous
def previous(entry)
next_or_previous(entry, 'lt', 'gt')
end
- # Engine: content_type.entries.klass.send(:group_by_select_option, name, content_type.order_by_definition)
- def group_by_select_option(type, name)
- return {} if type.nil? || name.nil? || type.fields_by_name[name].type != :select
+ def group_by_select_option(name)
+ return {} if name.nil? || content_type.nil? || content_type.fields_by_name[name].type != :select
- raise 'TODO: implement the group_by method'
- _groups = all(type).group_by(&name)
+ _groups = all.group_by { |entry| i18n_value_of(entry, name) }
- groups = content_type_repository.select_options(type, name).map do |option|
+ groups = content_type_repository.select_options(content_type, name).map do |option|
{ name: option, entries: _groups.delete(option) || [] }
end
@@ @@ -119,79 +80,81 @@ module Locomotive
private
- def scoped_query(type, &block)
- self.content_type = type
- query(&block)
- end
-
- def mapper(memoized = true)
- super(false).tap do |mapper|
+ def mapper(memoized = false)
+ super(memoized).tap do |mapper|
unless self.content_type.localized_fields_names.blank?
mapper.localized_attributes(*self.content_type.localized_fields_names)
end
- end
- end
- def type_from(slug)
- content_type_repository.by_slug(slug)
- end
-
- def localized_slug(entry)
- raise 'SHOULD NOT BE USED'
- localized_attribute(entry, :_slug)
- end
-
- def association(metadata, conditions = {})
- case metadata.type
- when :belongs_to then belongs_to_association(metadata)
- when :has_many then has_many_association(metadata, conditions)
- when :many_to_many then many_to_many_association(metadata, conditions)
+ self.content_type.belongs_to_fields.each do |field|
+ mapper.belongs_to_association(field.name, self.class, {}) do |repository|
+ # TODO: load the content type (adapter.id_names[:content_types])
+ repository.content_type
+ end # field.association_options)
+ end
end
end
- def belongs_to_association(metadata)
- type = type_from(metadata.target_class_slug)
- by_slug(type, metadata.target_slugs.first)
+ def prepare_conditions(*conditions)
+ [*conditions].inject({}) do |memo, hash|
+ memo.merge!(hash) unless hash.blank?
+ memo
+ end.merge(@local_conditions)
end
- def has_many_association(metadata, conditions)
- many_association(metadata,
- { metadata.target_field => localized_slug(metadata.source) }.merge(conditions))
- end
+ # def type_from(slug)
+ # content_type_repository.by_slug(slug)
+ # end
- def many_to_many_association(metadata, conditions)
- many_association(metadata,
- { '_slug.in' => metadata.target_slugs }.merge(conditions))
- end
+ # def localized_slug(entry)
+ # raise 'SHOULD NOT BE USED'
+ # localized_attribute(entry, :_slug)
+ # end
- def many_association(metadata, conditions)
- type = type_from(metadata.target_class_slug)
+ # def association(metadata, conditions = {})
+ # case metadata.type
+ # when :belongs_to then belongs_to_association(metadata)
+ # when :has_many then has_many_association(metadata, conditions)
+ # when :many_to_many then many_to_many_association(metadata, conditions)
+ # end
+ # end
- if order_by = metadata.order_by
- conditions = { order_by: order_by }.merge(conditions)
- end
+ # def belongs_to_association(metadata)
+ # type = type_from(metadata.target_class_slug)
+ # by_slug(type, metadata.target_slugs.first)
+ # end
- all(type, conditions)
- end
+ # def has_many_association(metadata, conditions)
+ # many_association(metadata,
+ # { metadata.target_field => localized_slug(metadata.source) }.merge(conditions))
+ # end
+
+ # def many_to_many_association(metadata, conditions)
+ # many_association(metadata,
+ # { '_slug.in' => metadata.target_slugs }.merge(conditions))
+ # end
- # def memoized_collection(content_type)
- # slug = content_type.slug
- # @collections ||= {}
+ # def many_association(metadata, conditions)
+ # type = type_from(metadata.target_class_slug)
- # return @collections[slug] if @collections[slug]
+ # if order_by = metadata.order_by
+ # conditions = { order_by: order_by }.merge(conditions)
+ # end
- # @collections[slug] = collection(content_type)
+ # all(type, conditions)
# end
def next_or_previous(entry, asc_op, desc_op)
return nil if entry.nil?
- type = entry.content_type
- column, direction = type.order_by.split
- operator = direction == 'asc' ? asc_op : desc_op
- value = localized_attribute(entry, column)
+ with(entry.content_type)
+
+ name, direction = self.content_type.order_by.split
+ op = direction == 'asc' ? asc_op : desc_op
+
+ conditions = prepare_conditions({ k(name, op) => i18n_value_of(entry, name) })
- query(type) { where("#{column}.#{operator}" => value) }.first
+ first { where(conditions) }
end
end
locomotive/steam/repositories/content_type_field_repository.rb b/lib/locomotive/steam/repositories/content_type_field_repository.rb +6 -3
@@ @@ -11,8 +11,7 @@ module Locomotive
mapping :content_type_fields, entity: ContentTypeField do
default_attribute :content_type, -> (repository) { repository.content_type }
- # embedded association
- association :select_options, ContentTypeFieldSelectOptionRepository
+ embedded_association :select_options, ContentTypeFieldSelectOptionRepository
end
def unique
@@ @@ -26,12 +25,16 @@ module Locomotive
query { where(required: true) }.all
end
+ def belongs_to
+ query { where(type: :belongs_to) }.all
+ end
+
def localized_names
query { where(localized: true) }.all.map(&:name)
end
def select_options(name)
- if field = first { where(name: name, type: 'select') }
+ if field = first { where(name: name, type: :select) }
field.select_options.all
else
nil
locomotive/steam/repositories/content_type_repository.rb b/lib/locomotive/steam/repositories/content_type_repository.rb +1 -2
@@ @@ -7,8 +7,7 @@ module Locomotive
# Entity mapping
mapping :content_types, entity: ContentType do
- # embedded association
- association :entries_custom_fields, ContentTypeFieldRepository
+ embedded_association :entries_custom_fields, ContentTypeFieldRepository
end
def by_slug(slug_or_content_type)
locomotive/steam/repositories/page_repository.rb b/lib/locomotive/steam/repositories/page_repository.rb +1 -4
@@ @@ -9,8 +9,7 @@ module Locomotive
mapping :pages, entity: Page do
localized_attributes :title, :slug, :permalink, :template, :template_path, :redirect_url, :fullpath, :seo_title, :meta_description, :meta_keywords
- # embedded association
- association :editable_elements, EditableElementRepository
+ embedded_association :editable_elements, EditableElementRepository
end
def all(conditions = {})
@@ @@ -29,8 +28,6 @@ module Locomotive
end
def matching_fullpath(list)
- # all(:fullpath.in => list)
- # all('fullpath.in' => list) # MongoDB => fullpath.in
all(k(:fullpath, :in) => list)
end
spec/unit/adapters/filesystem/yaml_loaders/content_entry_spec.rb +14 -1
@@ @@ -6,7 +6,7 @@ require_relative '../../../../../lib/locomotive/steam/adapters/filesystem/yaml_l
describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
let(:site_path) { default_fixture_site_path }
- let(:content_type) { instance_double('Articles', slug: 'bands') }
+ let(:content_type) { instance_double('Bands', slug: 'bands', belongs_to_fields: []) }
let(:scope) { instance_double('Scope', locale: :en, context: { content_type: content_type }) }
let(:loader) { described_class.new(site_path) }
@@ @@ -20,6 +20,19 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
expect(subject.first[:content_type]).to eq nil
end
+ context 'a content type with a belongs_to field' do
+
+ let(:field) { instance_double('Field', name: 'band') }
+ let(:content_type) { instance_double('Songs', slug: 'songs', belongs_to_fields: [field]) }
+
+ it 'adds a new attribute for the foreign key' do
+ expect(subject.first[:band_id]).to eq 'pearl-jam'
+ expect(subject.first[:band]).to eq nil
+ expect(subject.first[:_position_in_band]).to eq 0
+ end
+
+ end
+
end
end
spec/unit/entities/content_entry_spec.rb +27 -27
@@ @@ -12,7 +12,7 @@ describe Locomotive::Steam::ContentEntry do
describe '#valid?' do
- let(:fields) { [instance_double('Field', name: :title, type: 'string', required: true)] }
+ let(:fields) { [instance_double('Field', name: :title, type: :string, required: true)] }
before do
allow(repository).to receive(:required).and_return(fields)
@@ @@ -150,32 +150,32 @@ describe Locomotive::Steam::ContentEntry do
end
end
- context 'a belongs_to relationship' do
- let(:field_type) { :belongs_to }
- let(:value) { 'john-doe' }
- it { expect(subject.type).to eq :belongs_to }
- it { expect(subject.target_slugs).to eq ['john-doe'] }
- it { expect(subject.source).to eq content_entry }
- it { expect(subject.field).to eq field }
- end
-
- context 'a has_many relationship' do
- let(:field_type) { :has_many }
- let(:value) { nil }
- it { expect(subject.type).to eq :has_many }
- it { expect(subject.target_slugs).to eq [] }
- it { expect(subject.source).to eq content_entry }
- it { expect(subject.field).to eq field }
- end
-
- context 'a many_to_many relationship' do
- let(:field_type) { :many_to_many }
- let(:value) { ['john-doe', 'jane-doe'] }
- it { expect(subject.type).to eq :many_to_many }
- it { expect(subject.target_slugs).to eq ['john-doe', 'jane-doe'] }
- it { expect(subject.source).to eq content_entry }
- it { expect(subject.field).to eq field }
- end
+ # context 'a belongs_to relationship' do
+ # let(:field_type) { :belongs_to }
+ # let(:value) { 'john-doe' }
+ # it { expect(subject.type).to eq :belongs_to }
+ # it { expect(subject.target_slugs).to eq ['john-doe'] }
+ # it { expect(subject.source).to eq content_entry }
+ # it { expect(subject.field).to eq field }
+ # end
+
+ # context 'a has_many relationship' do
+ # let(:field_type) { :has_many }
+ # let(:value) { nil }
+ # it { expect(subject.type).to eq :has_many }
+ # it { expect(subject.target_slugs).to eq [] }
+ # it { expect(subject.source).to eq content_entry }
+ # it { expect(subject.field).to eq field }
+ # end
+
+ # context 'a many_to_many relationship' do
+ # let(:field_type) { :many_to_many }
+ # let(:value) { ['john-doe', 'jane-doe'] }
+ # it { expect(subject.type).to eq :many_to_many }
+ # it { expect(subject.target_slugs).to eq ['john-doe', 'jane-doe'] }
+ # it { expect(subject.source).to eq content_entry }
+ # it { expect(subject.field).to eq field }
+ # end
end
spec/unit/entities/content_type_field_spec.rb +14 -0
@@ @@ -0,0 +1,14 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::ContentTypeField do
+
+ let(:content_type) { described_class.new(name: 'title', type: 'string') }
+
+ describe '#type' do
+
+ subject { content_type.type }
+ it { is_expected.to eq :string }
+
+ end
+
+ end
spec/unit/models/mapper_spec.rb +1 -1
@@ @@ -36,7 +36,7 @@ describe Locomotive::Steam::Models::Mapper do
let(:repository) { instance_double('Repository', scope: 42) }
let(:attributes) { { parents: [instance_double('Page', title: 'Hello world')] } }
let(:klass) { instance_double('RepositoryKlass')}
- let(:block) { ->(_) { association(:parents, BlankRepository) } }
+ let(:block) { ->(_) { embedded_association(:parents, BlankRepository) } }
it { expect(subject.parents).not_to eq nil }
spec/unit/repositories/content_entry_repository_spec.rb +147 -126
@@ @@ -4,7 +4,7 @@ require_relative '../../../lib/locomotive/steam/adapters/filesystem.rb'
describe Locomotive::Steam::ContentEntryRepository do
- let(:type) { instance_double('Articles', _id: 1, slug: 'articles', order_by: nil, label_field_name: :title, localized_fields_names: [:title], fields_by_name: { title: instance_double('Field', name: :title, type: :string) }) }
+ let(:type) { instance_double('Articles', _id: 1, slug: 'articles', order_by: nil, label_field_name: :title, localized_fields_names: [:title], belongs_to_fields: [], fields_by_name: { title: instance_double('Field', name: :title, type: :string) }) }
let(:entries) { [{ content_type_id: 1, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' }] }
let(:locale) { :en }
let(:site) { instance_double('Site', _id: 1, default_locale: :en, locales: %i(en fr)) }
@@ @@ -18,17 +18,37 @@ describe Locomotive::Steam::ContentEntryRepository do
adapter.cache = NoCacheStore.new
end
+ describe 'belongs_to' do
+
+ let(:field) { instance_double('Field', name: :author, type: :belongs_to, association_options: { class_name: 'authors' }) }
+ let(:type) { instance_double('Articles', _id: 1, slug: 'articles', order_by: nil, label_field_name: :title, belongs_to_fields: [field], fields_by_name: { title: instance_double('Field', name: :title, type: :string), author: field }, localized_fields_names: []) }
+ let(:other_type) { instance_double('Authors', _id: 2, slug: 'authors', order_by: nil, label_field_name: :name, fields_by_name: { name: instance_double('Field', name: :name, type: :string) }, localized_fields_names: []) }
+ let(:entries) { [{ content_type_id: 1, title: 'Hello world', author_id: 'john-doe' }] }
+
+ let(:type_repository) { instance_double('ContentTypeRepository', belongs_to: [field]) }
+
+ before do
+ allow(type).to receive(:fields).and_return(type_repository)
+ end
+
+ subject { repository.with(type).by_slug('hello-world') }
+
+ it { expect(subject.author.class).to eq Locomotive::Steam::Models::BelongsToAssociation }
+ # it { expect(subject.author.name).to eq 'John Doe' }
+
+ end
+
describe '#all' do
let(:conditions) { nil }
- subject { repository.all(type, conditions) }
+ subject { repository.with(type).all(conditions) }
it { expect(subject.size).to eq 1 }
describe 'first element' do
- subject { repository.all(type, conditions).first }
+ subject { repository.with(type).all(conditions).first }
it { expect(subject.class).to eq Locomotive::Steam::ContentEntry }
it { expect(subject._label.translations).to eq('en' => 'Update #1', 'fr' => 'Mise a jour #1') }
@@ @@ -40,66 +60,67 @@ describe Locomotive::Steam::ContentEntryRepository do
end
- # describe '#build' do
+ describe '#build' do
- # let(:attributes) { { title: 'Hello world' } }
- # subject { repository.build(type, attributes) }
+ let(:attributes) { { title: 'Hello world' } }
+ subject { repository.with(type).build(attributes) }
- # it { expect(subject.title).to eq 'Hello world' }
+ it { expect(subject.title[:en]).to eq 'Hello world' }
+ it { expect(subject.content_type).to eq type }
- # end
+ end
# describe '#persist' do
- # let(:entry) { instance_double('NewEntry', _visible: true, content_type: type, _label: 'Hello world', attributes: { title: 'Hello world' }) }
- # subject { repository.persist(entry) }
+ # # let(:entry) { instance_double('NewEntry', _visible: true, content_type: type, _label: 'Hello world', attributes: { title: 'Hello world' }) }
+ # # subject { repository.persist(entry) }
- # before do
- # expect(entry).to receive(:[]).with(:_slug).and_return(nil)
- # expect(entry).to receive(:[]=).with(:_slug, 'hello-world')
- # expect(loader).to receive(:write).with(type, { title: 'Hello world' })
- # end
+ # # before do
+ # # expect(entry).to receive(:[]).with(:_slug).and_return(nil)
+ # # expect(entry).to receive(:[]=).with(:_slug, 'hello-world')
+ # # expect(loader).to receive(:write).with(type, { title: 'Hello world' })
+ # # end
- # it { expect { subject }.to change { repository.all(type).size }.by(1) }
+ # # it { expect { subject }.to change { repository.all(type).size }.by(1) }
# end
- # describe '#exists?' do
+ describe '#exists?' do
- # let(:conditions) { {} }
- # subject { repository.exists?(type, conditions) }
+ let(:conditions) { {} }
+ subject { repository.with(type).exists?(conditions) }
- # it { expect(subject).to eq true }
+ it { expect(subject).to eq true }
- # context 'more specific conditions' do
+ context 'more specific conditions' do
- # let(:conditions) { { '_slug' => 'update-number-1' } }
- # it { expect(subject).to eq true }
+ let(:conditions) { { '_slug' => 'update-number-1' } }
+ it { expect(subject).to eq true }
- # end
+ end
- # context 'conditions which do match any entries' do
+ context 'conditions which do match any entries' do
- # let(:conditions) { { '_slug' => 'foo' } }
- # it { expect(subject).to eq false }
+ let(:conditions) { { '_slug' => 'foo' } }
+ it { expect(subject).to eq false }
- # end
+ end
- # end
+ end
- # describe '#by_slug' do
+ describe '#by_slug' do
- # let(:slug) { nil }
- # subject { repository.by_slug(type, slug) }
+ let(:slug) { nil }
+ subject { repository.with(type).by_slug(slug) }
- # it { is_expected.to eq nil }
+ it { is_expected.to eq nil }
- # context 'existing slug' do
- # let(:slug) { 'update-number-1' }
- # it { expect(subject.title).to eq({ en: 'Update #1', fr: 'Mise a jour #1' }) }
- # end
+ context 'existing slug' do
+ let(:slug) { 'update-number-1' }
+ it { expect(subject.title.translations).to eq('en' => 'Update #1', 'fr' => 'Mise a jour #1') }
+ end
- # end
+ end
# describe '#value_for' do
@@ @@ -132,138 +153,138 @@ describe Locomotive::Steam::ContentEntryRepository do
# end
- # context 'has_many association' do
+ # # context 'has_many association' do
- # let(:association) { instance_double('Association', type: :has_many, association: true, target_class_slug: :authors, target_field: :article, order_by: 'created_at') }
- # let(:name) { :authors }
+ # # let(:association) { instance_double('Association', type: :has_many, association: true, target_class_slug: :authors, target_field: :article, order_by: 'created_at') }
+ # # let(:name) { :authors }
- # before do
- # allow(association).to receive(:source).and_return(entry)
- # expect(repository).to receive(:all).with(:author_type, { article: 'hello-world', order_by: 'created_at' }).and_return(%w(jane john))
- # end
+ # # before do
+ # # allow(association).to receive(:source).and_return(entry)
+ # # expect(repository).to receive(:all).with(:author_type, { article: 'hello-world', order_by: 'created_at' }).and_return(%w(jane john))
+ # # end
- # it { expect(subject).to eq %w(jane john) }
+ # # it { expect(subject).to eq %w(jane john) }
- # end
+ # # end
- # context 'many_to_many association' do
+ # # context 'many_to_many association' do
- # let(:association) { instance_double('Association', type: :many_to_many, association: true, target_class_slug: :authors, target_slugs: %w(jane john), order_by: nil) }
- # let(:name) { :authors }
+ # # let(:association) { instance_double('Association', type: :many_to_many, association: true, target_class_slug: :authors, target_slugs: %w(jane john), order_by: nil) }
+ # # let(:name) { :authors }
- # before do
- # expect(repository).to receive(:all).with(:author_type, { '_slug.in' => %w(jane john) }).and_return(%w(jane john))
- # end
+ # # before do
+ # # expect(repository).to receive(:all).with(:author_type, { '_slug.in' => %w(jane john) }).and_return(%w(jane john))
+ # # end
- # it { expect(subject).to eq %w(jane john) }
+ # # it { expect(subject).to eq %w(jane john) }
- # end
+ # # end
# end
# end
- # describe '#next' do
+ describe '#next' do
- # let(:type) { instance_double('Articles', slug: 'articles', order_by: '_position asc', label_field_name: :title, localized_fields_names: [:title], fields_by_name: { title: instance_double('Field', name: :title, type: :string) }) }
- # let(:entries) do
- # [
- # { content_type: type, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' },
- # { content_type: type, _position: 1, _label: 'Update #2', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' },
- # { content_type: type, _position: 2, _label: 'Update #3', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' }
- # ]
- # end
+ let(:type) { instance_double('Articles', _id: 1, slug: 'articles', order_by: '_position asc', label_field_name: :title, localized_fields_names: [:title], belongs_to_fields: [], fields_by_name: { title: instance_double('Field', name: :title, type: :string) }) }
+ let(:entries) do
+ [
+ { content_type_id: 1, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' },
+ { content_type_id: 1, _position: 1, _label: 'Update #2', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' },
+ { content_type_id: 1, _position: 2, _label: 'Update #3', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' }
+ ]
+ end
- # let(:entry) { nil }
- # subject { repository.next(entry) }
+ let(:entry) { nil }
+ subject { repository.next(entry) }
- # it { is_expected.to eq nil }
+ it { is_expected.to eq nil }
- # context 'being last' do
+ context 'being last' do
- # let(:entry) { instance_double('Entry', content_type: type, _position: 2) }
- # it { repository.send(:collection, type).inspect; is_expected.to eq nil }
+ let(:entry) { instance_double('Entry', content_type: type, _position: 2) }
+ it { is_expected.to eq nil }
- # end
+ end
- # context 'being middle' do
+ context 'being middle' do
- # let(:entry) { instance_double('Entry', content_type: type, _position: 1) }
- # it { expect(subject._position).to eq 2 }
+ let(:entry) { instance_double('Entry', content_type: type, _position: 1) }
+ it { expect(subject._position).to eq 2 }
- # end
+ end
- # end
+ end
- # describe '#previous' do
+ describe '#previous' do
- # let(:type) { instance_double('Articles', slug: 'articles', order_by: '_position asc', label_field_name: :title, localized_fields_names: [:title], fields_by_name: { title: instance_double('Field', name: :title, type: :string) }) }
- # let(:entries) do
- # [
- # { content_type: type, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' },
- # { content_type: type, _position: 1, _label: 'Update #2', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' },
- # { content_type: type, _position: 2, _label: 'Update #3', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' }
- # ]
- # end
+ let(:type) { instance_double('Articles', _id: 1, slug: 'articles', order_by: '_position asc', label_field_name: :title, localized_fields_names: [:title], belongs_to_fields: [], fields_by_name: { title: instance_double('Field', name: :title, type: :string) }) }
+ let(:entries) do
+ [
+ { content_type_id: 1, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' },
+ { content_type_id: 1, _position: 1, _label: 'Update #2', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' },
+ { content_type_id: 1, _position: 2, _label: 'Update #3', title: { fr: 'Mise a jour #2' }, text: { en: 'bla bla', fr: 'blabbla' }, date: '2009/05/12', category: 'General' }
+ ]
+ end
- # let(:entry) { nil }
- # subject { repository.previous(entry) }
+ let(:entry) { nil }
+ subject { repository.previous(entry) }
- # it { is_expected.to eq nil }
+ it { is_expected.to eq nil }
- # context 'being first' do
+ context 'being first' do
- # let(:entry) { instance_double('Entry', content_type: type, _position: 0) }
- # it { repository.send(:collection, type).inspect; is_expected.to eq nil }
+ let(:entry) { instance_double('Entry', content_type: type, _position: 0) }
+ it { is_expected.to eq nil }
- # end
+ end
- # context 'being middle' do
+ context 'being middle' do
- # let(:entry) { instance_double('Entry', content_type: type, _position: 1) }
- # it { expect(subject._position).to eq 0 }
+ let(:entry) { instance_double('Entry', content_type: type, _position: 1) }
+ it { expect(subject._position).to eq 0 }
- # end
+ end
- # end
+ end
- # describe '#group_by_select_option' do
+ describe '#group_by_select_option' do
- # let(:type) { nil }
- # let(:name) { nil }
+ let(:type) { nil }
+ let(:name) { nil }
- # subject { repository.group_by_select_option(type, name) }
+ subject { repository.with(type).group_by_select_option(name) }
- # it { is_expected.to eq({}) }
+ it { is_expected.to eq({}) }
- # context 'select field' do
+ context 'select field' do
- # let(:fields) do
- # {
- # title: instance_double('TitleField', name: :title, type: :string),
- # category: instance_double('SelectField', name: :category, type: :select, select_options: { en: ['cooking', 'bread'], fr: ['cuisine', 'pain'] })
- # }
- # end
- # let(:type) { instance_double('Articles', slug: 'articles', order_by: '_position asc', label_field_name: :title, localized_fields_names: [:title, :category], fields_by_name: fields) }
- # let(:name) { :category }
-
- # let(:entries) do
- # [
- # { content_type: type, _position: 0, _label: 'Recipe #1', category: 'cooking' },
- # { content_type: type, _position: 1, _label: 'Recipe #2', category: 'bread' },
- # { content_type: type, _position: 2, _label: 'Recipe #3', category: 'bread' },
- # { content_type: type, _position: 3, _label: 'Recipe #4', category: 'unknown' }
- # ]
- # end
+ let(:fields) do
+ {
+ title: instance_double('TitleField', name: :title, type: :string),
+ category: instance_double('SelectField', name: :category, type: :select, select_options: { en: ['cooking', 'bread'], fr: ['cuisine', 'pain'] })
+ }
+ end
+ let(:type) { instance_double('Articles', _id: 1, slug: 'articles', order_by: '_position asc', label_field_name: :title, localized_fields_names: [:title, :category], belongs_to_fields: [], fields_by_name: fields) }
+ let(:name) { :category }
- # before { allow(content_type_repository).to receive(:select_options).and_return(%w(cooking wine bread)) }
+ let(:entries) do
+ [
+ { content_type_id: 1, _position: 0, _label: 'Recipe #1', category: 'cooking' },
+ { content_type_id: 1, _position: 1, _label: 'Recipe #2', category: 'bread' },
+ { content_type_id: 1, _position: 2, _label: 'Recipe #3', category: 'bread' },
+ { content_type_id: 1, _position: 3, _label: 'Recipe #4', category: 'unknown' }
+ ]
+ end
- # it { expect(subject.size).to eq 4 }
- # it { expect(subject.map { |h| h[:name] }).to eq ['cooking', 'wine', 'bread', nil] }
- # it { expect(subject.map { |h| h[:entries].size }).to eq [1, 0, 2, 1] }
+ before { allow(content_type_repository).to receive(:select_options).and_return(%w(cooking wine bread)) }
- # end
+ it { expect(subject.size).to eq 4 }
+ it { expect(subject.map { |h| h[:name] }).to eq ['cooking', 'wine', 'bread', nil] }
+ it { expect(subject.map { |h| h[:entries].size }).to eq [1, 0, 2, 1] }
- # end
+ end
+
+ end
end
spec/unit/repositories/content_type_repository_spec.rb +1 -1
@@ @@ -105,7 +105,7 @@ describe Locomotive::Steam::ContentTypeRepository do
let(:fields) do
[
{ name: 'title', hint: 'Title of the article', type: 'string' },
- { name: 'category', type: 'select', select_options: [{ name: { en: 'cooking', fr: 'cuisine' }, position: 0 }, { name: { en: 'bread', fr: 'pain' }, position: 1 }] }
+ { name: 'category', type: :select, select_options: [{ name: { en: 'cooking', fr: 'cuisine' }, position: 0 }, { name: { en: 'bread', fr: 'pain' }, position: 1 }] }
]
end
let(:name) { :category }