GithubHelp home page GithubHelp logo

ramansah / votex Goto Github PK

View Code? Open in Web Editor NEW
40.0 4.0 7.0 21 KB

Implements vote / like / follow functionality for Ecto models in Elixir. Inspired from Acts as Votable gem in Ruby on Rails

License: MIT License

Elixir 95.82% HTML 4.18%
phoenix-framework ecto hex votable likeable elixir acts-as-votable

votex's Introduction

travis

Votex

Implements ๐Ÿ‘ vote / โค๏ธ like / follow functionality for Ecto models in Elixir

Inspired from Acts as Votable โญ in Ruby on Rails

Features

  • Any model can be voted
  • Any model can vote
  • Supports self referential voting
  • Easy to understand syntax

Installation

Add Votex to your project dependencies mix.exs

defp deps do
  [{:votex, "~> 0.3.0"}]
end

Specify your root project's repo in config

config :votex, Votex.DB,
  repo: MyApp.Repo

Votex needs a table in DB to store votes information. Install votex and generate votex schema migration

mix deps.get
mix votex.gen.migration
mix ecto.migrate

Usage

Configure Models

defmodule User do
  use Ecto.Schema
  use Votex.Voter
end

defmodule Post do
  use Ecto.Schema
  use Votex.Votable
end

Vote / Unvote

post |> Post.vote_by user
user |> User.voted_for? post
# true
post |> Post.votes_for |> length
# 1

post |> Post.votes_for
[
  %{
    id: 1,
    votable_id: 3,
    votable_type: "posts",
    voter: %Sample.User{
      id: 5,
      name: "John"
    },
    voter_id: 5,
    voter_type: "users"
  }
]

post |> Post.unvote_by user

Self Referential Vote

defmodule User do
  use Ecto.Schema 
  use Votex.Voter
  use Votex.Votable
end

user2 |> User.vote_by user1
# {:ok, _}

Cleanup

Since polymorphic associations are not supported in Ecto and callbacks are deprecated, orphan votes need to be cleared when a parent entity is destroyed. Therefore, you need to call cleanup_votes when you delete a Voter or a Votable record.

# Delete user
Repo.delete(user) |> User.cleanup_votes

# Delete post
Repo.delete(post) |> Post.cleanup_votes

Cache Support

Some fields like total number of votes on a post can be cached in posts table to avoid extra calls to DB. Votex will update the field if present in schema.

defmodule Post do
  use Ecto.Schema
  use Votex.Votable

  schema "posts" do
    field(:cached_votes_for_total, :integer)
  end

  @fields ~w(cached_votes_for_total)a

  # Publicly accessible changeset for Votex to update field
  def changeset(post, attrs) do
    post
    |> cast(attrs, @fields)
    |> validate_required(@fields)
  end
end

The posts table will track total votes from now on

post |> Post.vote_by user
post = Repo.get(Post, 1)
post.cached_votes_for_total
# 5

votex's People

Contributors

ramansah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

votex's Issues

Dialyzer warnings, and how to deal with them

Hi again, and thanks for Votex! I can see this being very useful for me.

I'm fairly new to Elixir but I do want to make sure I can keep using Dialyzer so I'm trying to figure out how to reason about some of the warnings that Dialyzer is outputting with regards to this module.

By trying to create a self-referential voter/votee in my module App.User, I get these warnings:

image

Is there any contribution I can make to votex to make these go away?

Implement API for follower/followee relationship?

While I know I can use the voter language to accomplish the same thing it comes across as being kind of confusing to grok in actual usage. Is there any desire to expose follower/followee API's?

Not compatible with ecto_sql 3.0

When trying to install I get:

Failed to use "ecto" (versions 3.1.0 to 3.1.7) because
  votex (version 0.3.0) requires ~> 2.1

Is ecto 2.1 a necessity?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.