{"id":15288813,"url":"https://github.com/getstream/stream-rails","last_synced_at":"2025-10-08T18:24:14.585Z","repository":{"id":22355809,"uuid":"25691827","full_name":"GetStream/stream-rails","owner":"GetStream","description":"Rails Client - Build Activity Feeds \u0026 Streams with GetStream.io","archived":false,"fork":false,"pushed_at":"2023-05-25T14:00:55.000Z","size":149,"stargazers_count":258,"open_issues_count":6,"forks_count":34,"subscribers_count":51,"default_branch":"main","last_synced_at":"2025-05-15T22:42:23.665Z","etag":null,"topics":["activity-stream","feed","getstream-io","news-feed","notification-feed","ruby","ruby-on-rails","stream-rails","timeline"],"latest_commit_sha":null,"homepage":"https://getstream.io","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GetStream.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-10-24T14:16:45.000Z","updated_at":"2025-01-21T23:02:11.000Z","dependencies_parsed_at":"2024-06-19T01:53:59.173Z","dependency_job_id":"15d7851d-af14-4bc0-9c9c-d637a651f3a3","html_url":"https://github.com/GetStream/stream-rails","commit_stats":{"total_commits":140,"total_committers":22,"mean_commits":6.363636363636363,"dds":0.7071428571428571,"last_synced_commit":"fbb92df21f1e3e759b7729f1cb051ce340c14eee"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GetStream","download_url":"https://codeload.github.com/GetStream/stream-rails/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activity-stream","feed","getstream-io","news-feed","notification-feed","ruby","ruby-on-rails","stream-rails","timeline"],"created_at":"2024-09-30T15:53:16.905Z","updated_at":"2025-10-08T18:24:14.520Z","avatar_url":"https://github.com/GetStream.png","language":"Ruby","readme":"# Stream Rails \u003c!-- omit in toc --\u003e\n\n[![build](https://github.com/GetStream/stream-rails/workflows/build/badge.svg)](https://github.com/GetStream/stream-rails/actions)\n[![Gem Version](https://badge.fury.io/rb/stream_rails.svg)](http://badge.fury.io/rb/stream_rails)\n\n[stream-rails](https://github.com/GetStream/stream-rails) is a Ruby on Rails client for [Stream](https://getstream.io/).\n\nYou can sign up for a Stream account at https://getstream.io/get_started.\n\nNote there is also a lower level [Ruby - Stream integration](https://github.com/getstream/stream-ruby) library which is suitable for all Ruby applications.\n\n\u003e 💡 This is a library for the **Feeds** product. The Chat SDKs can be found [here](https://getstream.io/chat/docs/).\n\n### Activity Streams \u0026 Newsfeeds\n\n![](https://dvqg2dogggmn6.cloudfront.net/images/mood-home.png)\n\nWhat you can build:\n\n- Activity streams such as seen on Github\n- A twitter style newsfeed\n- A feed like instagram/ pinterest\n- Facebook style newsfeeds\n- A notification system\n\n### Demo\n\nYou can check out our example app built using this library on Github [https://github.com/GetStream/Stream-Example-Rails](https://github.com/GetStream/Stream-Example-Rails)\n\n### Table of Contents\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Activity Streams \u0026 Newsfeeds](#activity-streams--newsfeeds)\n- [Demo](#demo)\n- [Table of Contents](#table-of-contents)\n- [Gem installation](#gem-installation)\n- [Setup](#setup)\n- [Supported ORMs](#supported-orms)\n  - [ActiveRecord](#activerecord)\n  - [Sequel](#sequel)\n- [Model configuration](#model-configuration)\n  - [Activity fields](#activity-fields)\n  - [Activity extra data](#activity-extra-data)\n  - [Activity creation](#activity-creation)\n- [Feed manager](#feed-manager)\n  - [Feeds bundled with feed_manager](#feeds-bundled-with-feed_manager)\n    - [User feed:](#user-feed)\n    - [News feeds:](#news-feeds)\n    - [Notification feed:](#notification-feed)\n  - [Follow a feed](#follow-a-feed)\n- [Showing the newsfeed](#showing-the-newsfeed)\n  - [Activity enrichment](#activity-enrichment)\n  - [Templating](#templating)\n  - [Pagination](#pagination)\n- [Disable model tracking](#disable-model-tracking)\n- [Running specs](#running-specs)\n- [Full documentation and Low level APIs access](#full-documentation-and-low-level-apis-access)\n- [Copyright and License Information](#copyright-and-license-information)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n### Gem installation\n\nYou can install `stream_rails` as you would any other gem:\n\n```\ngem install stream_rails\n```\n\nor in your Gemfile:\n\n```\ngem 'stream_rails'\n```\n\nThis library is tested against and fully supports the following Rails versions:\n\n- 5.0\n- 5.2\n- 6.0\n- 6.1\n\n### Setup\n\nLogin with Github on getstream.io and get your `api_key` and `api_secret` from your app configuration (Dashboard screen).\n\nThen you can add the StreamRails configuration in `config/initializers/stream_rails.rb`\n\n```ruby\nrequire 'stream_rails'\n\nStreamRails.configure do |config|\n  config.api_key      = \"YOUR API KEY\"\n  config.api_secret   = \"YOUR API SECRET\"\n  config.timeout      = 30                  # Optional, defaults to 3\n  config.location     = 'us-east'           # Optional, defaults to 'us-east'\n  config.api_hostname = 'stream-io-api.com' # Optional, defaults to 'stream-io-api.com'\n  # If you use custom feed names, e.g.: timeline_flat, timeline_aggregated,\n  # use this, otherwise omit:\n  config.news_feeds = { flat: \"timeline_flat\", aggregated: \"timeline_aggregated\" }\n  # Point to the notifications feed group providing the name, omit if you don't\n  # have a notifications feed\n  config.notification_feed = \"notification\"\nend\n```\n\n### Supported ORMs\n\n#### ActiveRecord\n\nThe integration will look as follows:\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  include StreamRails::Activity\n  as_activity\n\n  def activity_object\n    self.item\n  end\nend\n```\n\n#### Sequel\n\nPlease, use Sequel `~5`.\n\nThe integration will look as follows:\n\n```ruby\nclass Pin \u003c Sequel::Model\n  include StreamRails::Activity\n  as_activity\n\n  def activity_object\n    self.item\n  end\nend\n```\n\n### Model configuration\n\nInclude StreamRails::Activity and add as_activity to the model you want to integrate with your feeds.\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  belongs_to :user\n  belongs_to :item\n\n  validates :item, presence: true\n  validates :user, presence: true\n\n  include StreamRails::Activity\n  as_activity\n\n  def activity_object\n    self.item\n  end\n\nend\n```\n\nEverytime a Pin is created it will be stored in the feed of the user that created it. When a Pin instance is deleted, the feed will be removed as well.\n\n#### Activity fields\n\nActiveRecord models are stored in your feeds as activities; Activities are objects that tell the story of a person performing an action on or with an object, in its simplest form, an activity consists of an actor, a verb, and an object. In order for this to happen your models need to implement these methods:\n\n**#activity_object** the object of the activity (eg. an AR model instance)\n\n**#activity_actor** the actor performing the activity -- this value also provides the feed name and feed ID to which the activity will be added.\n\nFor example, let's say a Pin was a polymorphic class that could belong to either a user (e.g. `User` ID: 1) or a company (e.g. `Company` ID: 1). In that instance, the below code would post the pin either to the `user:1` feed or the `company:1` feed based on its owner.\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  belongs_to :owner, :polymorphic =\u003e true\n  belongs_to :item\n\n  include StreamRails::Activity\n  as_activity\n\n  def activity_actor\n    self.owner\n  end\n\n  def activity_object\n    self.item\n  end\n\nend\n```\n\nThe `activity_actor` defaults to `self.user`\n\n\n**#activity_verb** the string representation of the verb (defaults to model class name)\n\nHere's a more complete example of the Pin class:\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  belongs_to :author\n  belongs_to :item\n\n  include StreamRails::Activity\n  as_activity\n\n  def activity_actor\n    self.author\n  end\n\n  def activity_object\n    self.item\n  end\n\nend\n```\n\n#### Activity extra data\n\nOften you'll want to store more data than just the basic fields. You achieve this by implementing `#activity_extra_data` in your model.\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  belongs_to :author\n  belongs_to :item\n\n  include StreamRails::Activity\n  as_activity\n\n  def activity_extra_data\n    {'is_retweet' =\u003e self.is_retweet}\n  end\n\n  def activity_object\n    self.item\n  end\n\nend\n```\n\n#### Activity creation\n\nIf you want to control when to create an activity you should implement\nthe `#activity_should_sync?` method in your model.\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  belongs_to :author\n  belongs_to :item\n\n  include StreamRails::Activity\n  as_activity\n\n  def activity_should_sync?\n    self.published\n  end\n\n  def activity_object\n    self.item\n  end\n\nend\n```\n\nThis will create an activity only when `self.published` is true.\n\n### Feed manager\n\n`stream_rails` comes with a Feed Manager class that helps with all common feed operations. You can get an instance of the manager with `StreamRails.feed_manager`.\n\n```ruby\nfeed = StreamRails.feed_manager.get_user_feed(current_user.id)\n```\n\n#### Feeds bundled with feed_manager\n\nTo get you started the manager has 4 feeds pre-configured. You can add more feeds if your application requires it.\nFeeds are divided into three categories.\n\n##### User feed:\n\nThe user feed stores all activities for a user. Think of it as your personal Facebook page. You can easily get this feed from the manager.\n\n```ruby\nfeed = StreamRails.feed_manager.get_user_feed(current_user.id)\n```\n\n##### News feeds:\n\nNews feeds store activities from the people you follow.\nThere is both a flat newsfeed (similar to twitter) and an aggregated newsfeed (like facebook).\n\n```php\nfeed = StreamRails.feed_manager.get_news_feeds(current_user.id)[:flat]\naggregated_feed = StreamRails.feed_manager.get_news_feeds(current_user.id)[:aggregated]\n```\n\n##### Notification feed:\n\nThe notification feed can be used to build notification functionality.\n\n![Notification feed](http://feedly.readthedocs.org/en/latest/_images/fb_notification_system.png)\n\nBelow we show an example of how you can read the notification feed.\n\n```ruby\nnotification_feed = StreamRails.feed_manager.get_notification_feed(current_user.id)\n\n```\n\nBy default the notification feed will be empty. You can specify which users to notify when your model gets created. In the case of a retweet you probably want to notify the user of the parent tweet.\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  belongs_to :author\n  belongs_to :item\n\n  include StreamRails::Activity\n  as_activity\n\n  def activity_notify\n    if self.is_retweet\n      [StreamRails.feed_manager.get_notification_feed(self.parent.user_id)]\n    end\n  end\n\n  def activity_object\n    self.item\n  end\n\nend\n```\n\nAnother example would be following a user. You would commonly want to notify the user which is being followed.\n\n```ruby\nclass Follow \u003c ActiveRecord::Base\n  belongs_to :user\n  belongs_to :target\n\n  validates :target_id, presence: true\n  validates :user, presence: true\n\n  include StreamRails::Activity\n  as_activity\n\n  def activity_notify\n    [StreamRails.feed_manager.get_notification_feed(self.target_id)]\n  end\n\n  def activity_object\n    self.target\n  end\n\nend\n```\n\n#### Follow a feed\n\nIn order to populate newsfeeds, you need to notify the system about follow relationships.\n\nThe current user's flat and aggregated feeds will follow the `target_user`'s user feed, with the following code:\n\n```\nStreamRails.feed_manager.follow_user(user_id, target_id)\n```\n\n![](http://i.imgur.com/bLywmPj.png)\n\n### Showing the newsfeed\n\n#### Activity enrichment\n\nWhen you read data from feeds, a pin activity will look like this:\n\n```json\n{ \"actor\": \"User:1\", \"verb\": \"like\", \"object\": \"Item:42\" }\n```\n\nThis is far from ready for usage in your template. We call the process of loading the references from the database\n\"enrichment.\" An example is shown below:\n\n```ruby\nenricher = StreamRails::Enrich.new\n\nfeed = StreamRails.feed_manager.get_news_feeds(current_user.id)[:flat]\nresults = feed.get()['results']\nactivities = enricher.enrich_activities(results)\n```\n\nA similar method called `enrich_aggregated_activities` is available for aggregated feeds.\n\n```ruby\nenricher = StreamRails::Enrich.new\n\nfeed = StreamRails.feed_manager.get_news_feeds(current_user.id)[:aggregated]\nresults = feed.get()['results']\nactivities = enricher.enrich_aggregated_activities(results)\n```\n\nIf you have additional metadata in your activity (by overriding `activity_extra_data` in the class where you add the\nStream Activity mixin), you can also enrich that field's data by doing the following:\n\nStep One: override the `activity_extra_data` method from our mixin:\n\n```ruby\nclass Pin \u003c ActiveRecord::Base\n  include StreamRails::Activity\n  as_activity\n\n  attr_accessor :extra_data\n\n  def activity_object\n    self.item\n  end\n\n  # override this method to add metadata to your activity\n  def activity_extra_data\n    @extra_data\n  end\nend\n```\n\nNow we'll create a 'pin' object which has a `location` metadata field. In this example, we will also have a\n`location` table and model, and we set up our metadata in the `extra_data` field. It is important that the\nsymbol of the metadata as well as the value of the meta data match this pattern. The left half of the\n`string:string` metadata value when split on `:` must also match the name of the model.\n\nWe must also tell the enricher to also fetch locations when looking through our activities\n\n```ruby\nboulder = Location.new\nboulder.name = \"Boulder, CO\"\nboulder.save!\n\n# tell the enricher to also do a lookup on the `location` model\nenricher.add_fields([:location])\n\npin = Pin.new\npin.user = @tom\npin.extra_data = {:location =\u003e \"location:#{boulder.id}\"}\n```\n\nWhen we retrieve the activity later, the enrichment process will include our `location` model as well, giving us\naccess to attributes and methods of the location model:\n\n```ruby\nplace = activity[:location].name\n# Boulder, CO\n```\n\n#### Templating\n\nNow that you've enriched the activities you can render them in a view.\nFor convenience we include a basic view:\n\n```\n\u003cdiv class=\"container\"\u003e\n    \u003cdiv class=\"container-pins\"\u003e\n        \u003c% for activity in @activities %\u003e\n            \u003c%= render_activity activity %\u003e\n        \u003c% end %\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n\nThe `render_activity` view helper will render the activity by picking the partial `activity/_pin` for a pin activity, `aggregated_activity/_follow` for an aggregated activity with verb follow.\n\nThe helper will automatically send `activity` to the local scope of the partial; additional parameters can be sent as well as use different layouts, and prefix the name\n\ne.g. renders the activity partial using the `small_activity` layout:\n\n```\n\u003c%= render_activity activity, :layout =\u003e \"small_activity\" %\u003e\n```\n\ne.g. prefixes the name of the template with \"notification\\_\":\n\n```\n\u003c%= render_activity activity, :prefix =\u003e \"notification_\" %\u003e\n```\n\ne.g. adds the extra_var to the partial scope:\n\n```\n\u003c%= render_activity activity, :locals =\u003e {:extra_var =\u003e 42} %\u003e\n```\n\ne.g. renders the activity partial using the `notifications` partial root, which will render the partial with the path `notifications/#{ACTIVITY_VERB}`\n\n```\n\u003c%= render_activity activity, :partial_root =\u003e \"notifications\" %\u003e\n```\n\n#### Pagination\n\nFor simple pagination you can use the [stream-ruby API](https://github.com/getstream/stream-ruby),\nas follows in your controller:\n\n```ruby\n  StreamRails.feed_manager.get_news_feeds(current_user.id)[:flat] # Returns a Stream::Feed object\n  results = feed.get(limit: 5, offset: 5)['results']\n```\n\n### Disable model tracking\n\nYou can disable model tracking (eg. when you run tests) via StreamRails.configure\n\n```\nrequire 'stream_rails'\n\nStreamRails.enabled = false\n```\n\n### Running specs\n\nFrom the project root directory:\n\n```\n./bin/run_tests.sh\n```\n\n### Full documentation and Low level APIs access\n\nWhen needed you can also use the [low level Ruby API](https://github.com/getstream/stream-ruby) directly. Documentation is available at the [Stream website](https://getstream.io/activity-feeds/docs/?language=ruby).\n\n### Copyright and License Information\n\nCopyright (c) 2014-2021 Stream.io Inc, and individual contributors. All rights reserved.\n\nSee the file \"LICENSE\" for information on the history of this software, terms \u0026 conditions for usage, and a DISCLAIMER OF ALL WARRANTIES.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetstream%2Fstream-rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetstream%2Fstream-rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetstream%2Fstream-rails/lists"}