0

I have tried to use

has_many :in, :ratings, unique: true, rel_class: Rating

But that unique: true is ignored because I have a model class for the relationship. How can I make sure that if my Users rate Articles, their rating gets updated instead of added. I'd prefer it if it produces a single query. ;-)

Article.rb:

class Article
  include Neo4j::ActiveNode
  property :title, type: String
  property :body, type: String

  property :created_at, type: DateTime
  # property :created_on, type: Date

  property :updated_at, type: DateTime
  # property :updated_on, type: Date

  has_many :in, :ratings, unique: true, rel_class: Rating
  has_many :in, :comments, unique: true, type: :comment_on
  has_one :in, :author, unique: true, type: :authored, model_class: User
end

User.rb:

class User
  include Neo4j::ActiveNode

  has_many :out, :articles, unique: true, type: :authored
  has_many :out, :comments, unique: true, type: :authored
  has_many :out, :ratings, unique: true, rel_class: Rating
  # this is a devise model, so there are many properties coming up here.

Rating.rb

class Rating
  include Neo4j::ActiveRel
  property :value, type: Integer

  from_class User
  to_class :any
  type 'rates'

  property :created_at, type: DateTime
  # property :created_on, type: Date

  property :updated_at, type: DateTime
  # property :updated_on, type: Date

end

Rating creation inside the article controller:

Rating.create(:value => params[:articleRating],
                       :from_node => current_user, :to_node => @article)
Joe Eifert
  • 1,306
  • 14
  • 29

2 Answers2

1

This has been resolved. You can ensure unique relationships while using an ActiveRel model by using the creates_unique keyword.

per https://stackoverflow.com/a/33153615

Community
  • 1
  • 1
0

For now I found this ugly workaround..

  def rate
    params[:articleRating]
    rel = current_user.rels(type: :rates, between: @article)
    if rel.nil? or rel.first.nil?
      Rating.create(:value => rating,
                    :from_node => current_user, :to_node => @article)
    else
      rel.first[:value] = rating
      rel.first.save
    end
    render text: ''
  end

EDIT: cleaner, but with two queries:

def rate
    current_user.rels(type: :rates, between: @article).each{|rel| rel.destroy}
    Rating.create(:value => params[:articleRating],
                    :from_node => current_user, :to_node => @article)
    render text: ''
  end
Joe Eifert
  • 1,306
  • 14
  • 29