diff --git a/app/controllers/management/carousels_controller.rb b/app/controllers/management/carousels_controller.rb
index b39f2c5bb0e2d4a120d6c6111dba53d9ff836c4b..9eb9c5e295db8333ece0da6cb17452b3707780e1 100644
--- a/app/controllers/management/carousels_controller.rb
+++ b/app/controllers/management/carousels_controller.rb
@@ -2,7 +2,7 @@ class Management::CarouselsController < ManagementController
   before_action :set_carousel, only: [:edit, :update, :destroy]
 
   def index
-    @carousels = carousel_repository.all
+    @carousels = Carousel.all
   end
 
   def new
@@ -13,7 +13,7 @@ class Management::CarouselsController < ManagementController
     @carousel = Carousel.new(carousel_params)
 
     respond_to do |format|
-      if carousel_repository.save @carousel
+      if @carousel.save
         format.html { redirect_to management_carousels_path }
       else
         format.html { render :new }
@@ -26,7 +26,7 @@ class Management::CarouselsController < ManagementController
 
   def update
     respond_to do |format|
-      if carousel_repository.update(@carousel, carousel_params)
+      if @carousel.update(carousel_params)
         format.html { redirect_to management_carousels_path }
       else
         format.html { render :edit }
@@ -36,7 +36,7 @@ class Management::CarouselsController < ManagementController
 
   def destroy
     @carousel.image = nil
-    carousel_repository.destroy @carousel
+    @carousel.destroy
     respond_to do |format|
       format.html { redirect_to management_carousels_path }
     end
@@ -45,7 +45,7 @@ class Management::CarouselsController < ManagementController
   private
 
   def set_carousel
-    @carousel = carousel_repository.find params[:id]
+    @carousel = Carousel.find params[:id]
   end
 
   def carousel_params
diff --git a/app/models/concerns/followable.rb b/app/models/concerns/followable.rb
index f2a8dd87c454951f2a4d4ad34d41d8e342162df5..743d8712f5933daa5a80e0211e41b71e3366d733 100644
--- a/app/models/concerns/followable.rb
+++ b/app/models/concerns/followable.rb
@@ -5,4 +5,16 @@ module Followable
     has_many :follows, as: :followable
   end
 
+  def follow(user)
+    Follow.create(user: user, followable: self)
+  end
+
+  def unfollow(user)
+    Follow.where(user: user, followable: self).destroy_all
+  end
+
+  def following?(user)
+    !follows.where(user: user).blank?
+  end
+
 end
\ No newline at end of file
diff --git a/app/models/concerns/metadatable.rb b/app/models/concerns/metadatable.rb
index 251527e94baa8e1dda76d7d7b9476e64c16ffc1d..46c6184a88ef967f7937167f7427f79ae35cb87f 100644
--- a/app/models/concerns/metadatable.rb
+++ b/app/models/concerns/metadatable.rb
@@ -9,6 +9,7 @@ module Metadatable
 
   def get_metadata_values_of key
     values = []
+    metadata = JSON.parse(metadata) if metadata.class == String
     unless metadata.blank?
       metadata.each do |m|
         m = m.with_indifferent_access
@@ -18,4 +19,10 @@ module Metadatable
     values
   end
 
+  #returns @metadata as hash
+  def metadata
+    @metadata
+    JSON.parse(@metadata) if @metadata.class == String
+  end
+
 end
diff --git a/app/models/concerns/sociable.rb b/app/models/concerns/sociable.rb
index c98a735612a5af5cffe1c478e4e59cdee936e529..21ce5ed2a0b626e175aac1f7cef3bfec4df91a21 100644
--- a/app/models/concerns/sociable.rb
+++ b/app/models/concerns/sociable.rb
@@ -8,4 +8,16 @@ module Sociable
     has_many :shares, as: :shareable
   end
 
+  def liked?(user)
+    !likes.where(user: user).blank?
+  end
+
+  def like(user)
+    Like.create(user: user, likeable: self)
+  end
+
+  def dislike(user)
+    Like.where(user: user, likeable: self).destroy_all
+  end
+
 end
\ No newline at end of file
diff --git a/app/models/concerns/stateful.rb b/app/models/concerns/stateful.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b0e24aa10de8d929e3b2b5804672d299d2272367
--- /dev/null
+++ b/app/models/concerns/stateful.rb
@@ -0,0 +1,20 @@
+module Stateful
+  extend ActiveSupport::Concern
+
+  included do
+    validates_presence_of :state
+  end
+
+  def is_published?
+    'published' == @state
+  end
+
+  def is_draft?
+    'draft' == @state
+  end
+
+  def publish
+    @state = 'published'
+  end
+
+end
\ No newline at end of file
diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb
index 0deef62269dbf0ad59d9c288f46f36656ada3e30..a4b74bc1a6ac4e558ecd21a6c32c2058685421c8 100644
--- a/app/models/learning_object.rb
+++ b/app/models/learning_object.rb
@@ -2,6 +2,7 @@ class LearningObject < ActiveRecord::Base
   include Metadatable
   include Reviewable
   include Sociable
+  include Stateful
 
   has_and_belongs_to_many :topics
 
@@ -9,6 +10,7 @@ class LearningObject < ActiveRecord::Base
   has_many :collections, through: :collection_items
 
   has_many :complaints
+  has_many :attachments, class_name: 'LearningObject::Attachment', dependent: :destroy
 
   belongs_to :publisher, polymorphic: true
 
@@ -31,17 +33,13 @@ class LearningObject < ActiveRecord::Base
     get_metadata_value_of 'dc.subject.category'
   end
 
-  def liked?(user)
-    return false if likes.where(user: user).blank?
-
-    true
-  end
-
-  def like(user)
-    Like.create(user: user, likeable: self)
+  def url_reference
+    get_metadata_value_of 'dc.object.url'
   end
 
-  def dislike(user)
-    Like.where(user: user, likeable: self).destroy_all
+  ##checks if learning object link to an url.
+  #returns boolean
+  def has_url_reference?
+    !url_reference.blank?
   end
 end
diff --git a/app/models/learning_object/attachment.rb b/app/models/learning_object/attachment.rb
index c46b3dfb8bc2b652db12f9da53a4ee82c4075b60..7b93f32b805630d528aba18fee9f16308b8f5393 100644
--- a/app/models/learning_object/attachment.rb
+++ b/app/models/learning_object/attachment.rb
@@ -1,6 +1,3 @@
-class LearningObject::Attachment
-  include ActiveModel::Model
-
-  #this attributes mirror Dspace bitstream values
-  attr_accessor :id, :name, :link, :retrieve_link, :description, :format, :mime_type, :size, :bundle_name
+class LearningObject::Attachment < ActiveRecord::Base
+  belongs_to :learning_object
 end
diff --git a/app/models/learning_object/draft.rb b/app/models/learning_object/draft.rb
index cee1b97ec8094b59979f51003be172b16387ca91..36c59c60019d40172a1b44314d67ac5f7f035b1b 100644
--- a/app/models/learning_object/draft.rb
+++ b/app/models/learning_object/draft.rb
@@ -1,17 +1,9 @@
 class LearningObject::Draft < LearningObject
 
-  def valid?
-    true
-  end
-
-  def to_orientdb_hash
-    super.merge('@class' => 'LearningObject')
-  end
-
-  private
-
-  def defaults
-    super.merge(status: 'draft')
+  ##overwrites initialize method to force @state value as draft
+  def initialize(attributes = nil, options = {})
+    super(attributes, options)
+    @state = 'draft'
   end
 
 end
\ No newline at end of file
diff --git a/app/models/learning_object/type.rb b/app/models/learning_object/type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5c7496f1c8a180fab03a32f80cd6813f361c95f8
--- /dev/null
+++ b/app/models/learning_object/type.rb
@@ -0,0 +1,5 @@
+class LearningObject::Type
+  URL_REFERENCE = 'url_reference'
+  VIDEO = 'video'
+  IMAGE = 'imagem'
+end
diff --git a/app/services/learning_object_publisher.rb b/app/services/learning_object_publisher.rb
index b1411633542cb4894b9ab7e55d4cfa765de1677a..8cd70b6dd788c2b509f29f3ab3aa265b71a52a13 100644
--- a/app/services/learning_object_publisher.rb
+++ b/app/services/learning_object_publisher.rb
@@ -1,39 +1,47 @@
 require 'dspace'
 
 class LearningObjectPublisher
-  include RepositoriesProxy
 
   def initialize(dspace_client)
     @dspace = dspace_client
   end
 
+  #create a learning object with draft status
+  #if draft#type is 'external link', then the draft is published.
   def create_draft(draft)
     item = @dspace.collections.create_item(build_dspace_item(draft), id: DspaceService::TEST_COLLECTION)
     draft.id_dspace = item.id
-    learning_object_repository.create draft
+    draft.save!
+    publish! draft if draft.has_url_reference?
+    draft
   end
 
+  #post *media_path* to *learning_object* on dspace
   def post(learning_object, media_path)
-    DspaceUploadWorker.perform_async learning_object.id_dspace, media_path
+    DspaceUploadWorker.perform_async learning_object.id, learning_object.id_dspace, media_path
   end
 
-  def publish(learning_object)
-    # change status
-    learning_object.status = 'active'
-    learning_object_repository.update_property(learning_object, 'status', learning_object.status)
+  ##publish *learning_object*
+  #this method will create thumbnails, change state to published and will save it.
+  def publish!(learning_object)
+    if learning_object.is_draft?
+      create_thumbnail! learning_object
+      learning_object.publish
+    end
 
-    # update bitstreams from attachments
-    #if !learning_object.attachments.nil?#
-#
-#    end
+    learning_object.save
   end
 
   private
 
+  def create_thumbnail!(learning_object)
+    #call thumbnail worker
+  end
+
   def build_dspace_item(draft)
-   ::Dspace::Item.new({
-                         'name' => draft.name
-                     })
+    ::Dspace::Item.new({
+                           'name' => draft.name
+                       })
   end
 
 end
\ No newline at end of file
diff --git a/app/workers/dspace_upload_worker.rb b/app/workers/dspace_upload_worker.rb
index ba58a5ed5f2e59f9a9abd9b7f04f5340fcc4197f..bd18a4bdd5370df1f74911ed2aa6283e08d31a27 100644
--- a/app/workers/dspace_upload_worker.rb
+++ b/app/workers/dspace_upload_worker.rb
@@ -3,21 +3,42 @@ class DspaceUploadWorker
 
   @@dspace= nil
 
-  def perform(item_id, media_path)
+  def perform(learning_object_id, item_id, media_path, *options)
+    # create file instance
     file = File.new(media_path, 'r')
-    bitstream = dspace.items.add_bitstream(file, id: item_id, name: File.basename(media_path), description: 'beta upload')
+
+    #create bitstream in dspace
+    bitstream = dspace.items.add_bitstream(file, id: item_id, name: File.basename(media_path), description: get_description(options))
+
+    #find learning object
+    learning_object = LearningObject.find learning_object_id
+    learning_object.attachments.create map_bitstream2attachment(bitstream)
+    publisher.publish! learning_object
   end
 
   private
 
-  def build_bistreams_string(bitstream)
-    JSON.generate({id: bitstream.id, name: bitstream.name, link: bitstream.link,
-      retrieveLink: bitstream.retrieve_link, description: bitstream.description,
-      format: bitstream.format, mimeType: bitstream.mime_type, size: bitstream.size_bytes, bundleName: bitstream.bundle_name})
+  def map_bitstream2attachment(bitstream)
+    {id_dspace: bitstream.id, name: bitstream.name, link: bitstream.link,
+     retrieve_link: bitstream.retrieve_link, description: bitstream.description,
+     format: bitstream.format, mime_type: bitstream.mime_type, size: bitstream.size_bytes,
+     bundle_name: bitstream.bundle_name}
+  end
+
+  def publisher
+    @publisher ||= LearningObjectPublisher.new(dspace)
   end
 
   def dspace
     @@dspace ||= DspaceService.create_client
   end
 
-end
+  def get_description(*options)
+    description = nil
+    if options.has_key? :description
+      description = options[:description]
+    end
+    description
+  end
+
+end
\ No newline at end of file
diff --git a/db/migrate/20160201135415_create_learning_object_attachments.rb b/db/migrate/20160201135415_create_learning_object_attachments.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fbcdecef74ce086e64edba3726739c4824526a6f
--- /dev/null
+++ b/db/migrate/20160201135415_create_learning_object_attachments.rb
@@ -0,0 +1,18 @@
+class CreateLearningObjectAttachments < ActiveRecord::Migration
+  def change
+    create_table :learning_object_attachments do |t|
+      t.string :name
+      t.string :link
+      t.string :retrieve_link
+      t.text :description
+      t.string :format
+      t.string :mime_type
+      t.integer :size
+      t.string :bundle_name
+      t.belongs_to :learning_object, index: true
+
+      t.timestamps null: false
+    end
+    add_foreign_key :learning_object_attachments, :learning_objects
+  end
+end
diff --git a/db/migrate/20160201140345_remove_bitstreams_column_from_learning_objects.rb b/db/migrate/20160201140345_remove_bitstreams_column_from_learning_objects.rb
new file mode 100644
index 0000000000000000000000000000000000000000..56da4dd0fffbfabf1e60ad481e3656b14208942c
--- /dev/null
+++ b/db/migrate/20160201140345_remove_bitstreams_column_from_learning_objects.rb
@@ -0,0 +1,5 @@
+class RemoveBitstreamsColumnFromLearningObjects < ActiveRecord::Migration
+  def change
+    remove_column :learning_objects, :bitstreams
+  end
+end
diff --git a/db/migrate/20160202121737_add_state_column_for_learning_objects.rb b/db/migrate/20160202121737_add_state_column_for_learning_objects.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3597ebca1ef2edf9ebeb18b1878e063192948cb4
--- /dev/null
+++ b/db/migrate/20160202121737_add_state_column_for_learning_objects.rb
@@ -0,0 +1,5 @@
+class AddStateColumnForLearningObjects < ActiveRecord::Migration
+  def change
+    add_column :learning_objects, :state, :string, default: 'published'
+  end
+end
diff --git a/db/migrate/20160202134938_add_id_dspace_column_for_attachments.rb b/db/migrate/20160202134938_add_id_dspace_column_for_attachments.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f11460ceea8cd04c5be23dfc8d5e6f9c3e0aa91d
--- /dev/null
+++ b/db/migrate/20160202134938_add_id_dspace_column_for_attachments.rb
@@ -0,0 +1,5 @@
+class AddIdDspaceColumnForAttachments < ActiveRecord::Migration
+  def change
+    add_column :learning_object_attachments, :id_dspace, :integer
+  end
+end
diff --git a/test/fixtures/learning_object/attachments.yml b/test/fixtures/learning_object/attachments.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cf9b5d498a8df28b59ea854eb13a353b00f3f5a6
--- /dev/null
+++ b/test/fixtures/learning_object/attachments.yml
@@ -0,0 +1,23 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  name: MyString
+  link: MyString
+  retrieve_link: MyString
+  description: MyText
+  format: MyString
+  mime_type: MyString
+  size: 1
+  bundle_name: MyString
+  learning_object_id: 
+
+two:
+  name: MyString
+  link: MyString
+  retrieve_link: MyString
+  description: MyText
+  format: MyString
+  mime_type: MyString
+  size: 1
+  bundle_name: MyString
+  learning_object_id: 
diff --git a/test/models/learning_object/attachment_test.rb b/test/models/learning_object/attachment_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bb5827e84db32533af7aec00b87dffd4effa6b7f
--- /dev/null
+++ b/test/models/learning_object/attachment_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class LearningObject::AttachmentTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end