ruby-on-rails – 使用after_save在Neo4J模型中创建关系

ruby-on-rails – 使用after_save在Neo4J模型中创建关系,第1张

概述所以我为这些问题看起来多么荒谬而道歉.我是rails的新手,作为第一个任务,我也带来了Neo4J,因为如果我发展这个项目,它似乎是最合适的. 我将解释 *** 作流程然后显示一些示例代码.我现在尝试在步骤3-5中添加. >用户通过FB登录 >第一次登录会创建一个用户节点.如果用户存在,它只是检索该用户节点 >创建用户节点后,使用koala gem访问FB Graph API >使用该应用程序检索每个朋友的 所以我为这些问题看起来多么荒谬而道歉.我是rails的新手,作为第一个任务,我也带来了Neo4J,因为如果我发展这个项目,它似乎是最合适的.

我将解释 *** 作流程然后显示一些示例代码.我现在尝试在步骤3-5中添加.

>用户通过FB登录
>第一次登录会创建一个用户节点.如果用户存在,它只是检索该用户节点
>创建用户节点后,使用koala gem访问FB Graph API
>使用该应用程序检索每个朋友的好友列表.
>浏览每个朋友,并在两个用户之间添加双向友谊关系

因为3-5只需要在用户第一次加入时发生,我想我可以在与after_save回调相关的方法中执行此 *** 作.这个逻辑有一个缺陷,因为我需要在某个时候用其他属性更新用户,它会再次调用after_save.我可以通过更新来防止这种情况发生吗?

SessionsController供参考

def create    user = User.from_omniauth(env["omniauth.auth"])    session[:user_ID] = user.ID      redirect_to root_url  end  def destroy    session.delete(:user_ID)    redirect_to root_path  end

所以在我的user.rb中我有这样的东西

has_many :both,:frIEndships  after_save :check_frIEnds  def self.from_omniauth(auth)    @user = User.where(auth.slice(:provIDer,:uID)).first    unless @user      @user = User.new      # assign a bunch of attributes to @user      @user.save!    end    return @user  end  def facebook    @facebook ||= Koala::Facebook::API.new(oauth_token)    block_given? ? yIEld(@facebook) : @facebook      rescue Koala::Facebook::APIError => e      logger.info e.to_s      nil  end  def frIEnds_count    facebook { |fb| fb.get_connection("me","frIEnds",summary: {}) }  end  def check_frIEnds(frIEndships)    facebook.get_connection("me","frIEnds").each do |frIEnd|      frIEnd_ID = frIEnd["ID"]      frIEnd_node = User.where(frIEnd_ID)      FrIEndship.create_frIEndship(user,frIEnd_node)      return true    end  end

frIEndship.rb

from_class User  to_class   User  type 'frIEndship'  def self.create_frIEndship(user,frIEnd_node)    frIEndship = FrIEndship.create(from_node: user,to_node: frIEnd_node)  end

我不确定我是否在如何创建关系节点的正确轨道上.在我刚刚创建@user时,如何将其合并到我的check_frIEnds方法中并正确检索用户和朋友节点,以便将两者链接在一起.

现在它不知道user和frIEnd_user是节点

如果你看到其他不良代码的做法,请告诉我!

提前:感谢@subvertallchris的帮助.我相信你会回答我的很多问题.

解决方法 这是一个非常好的问题!我认为你走的正确,但有一些事情你可以改变.

首先,您需要调整has_many方法.您的关联总是需要终止于节点,而不是ActiveRel类,因此您需要将其重写为如下所示:

has_many:both,:frIEnds,model_class:’User’,rel_class:’FrIEndship’

否则你会遇到一些问题.

您可能需要考虑重新命名您的关系类型,以符合Neo4j风格的一致性.我有很多不好的例子,如果我给你不好的想法,那就很抱歉. FRIENDS_WITH将是一个更好的关系名称.

至于处理你的大问题,你可以在这里做很多事情.

编辑!废话,我忘记了最重要的部分! ditch表示after_save回调并使加载存在/创建新用户行为两种方法.

class SessionsController < ApplicationController  def create    user = User.from_omniauth(env["omniauth.auth"])    @user = user.nil? ? User.create_from_omniauth(env["omniauth.auth"]) : user    session[:user_ID] = @user.ID    redirect_to root_url  end  def destroy    session.delete(:user_ID)    redirect_to root_path  endendclass User  include Neo4j::ActiveNode  # lots of other propertIEs  has_many :both,:frIEnds,model_class: 'User',rel_class: 'FrIEndship'  def self.from_omniauth(auth)    User.where(auth.slice(:provIDer,:uID)).limit(1).first  end  def self.create_from_omniauth(auth)    user = User.new    # assign a bunch of attributes to user    if user.save!      user.check_frIEnds    else      # raise an error -- your user was neither found nor created    end    user  end  # more stuffend

这将解决你的问题,让它开始.您可能希望将整个事物包装在事务中,因此请在Wiki中阅读.

但我们还没有完成.让我们来看看你原来的check_frIEnds:

def check_frIEnds(frIEndships)  facebook.get_connection("me","frIEnds").each do |frIEnd|    frIEnd_ID = frIEnd["ID"]    frIEnd_node = User.where(frIEnd_ID)    FrIEndship.create_frIEndship(user,frIEnd_node)    return true  endend

你实际上并没有把它作为一个论点,所以摆脱它.此外,如果您知道自己只是在寻找单个节点,请使用find_by.我将假设每个用户都有一个facebook_ID属性.

def check_frIEnds  facebook.get_connection("me","frIEnds").each do |frIEnd|    frIEnd_node = User.find_by(facebook_ID: frIEnd["ID"])    FrIEndship.create_frIEndship(user,frIEnd_node) unless frIEnd_node.blank?  endend

create_frIEndship方法应该返回true或false,所以只要使方法的最后一个语句执行该 *** 作,您就可以返回它返回的内容.这很容易:

def self.create_frIEndship(user,frIEnd_node)  FrIEndship.new(from_node: user,to_node: frIEnd_node).saveend

create不返回true或false,它返回结果对象,因此链接保存到新对象将获得您想要的.除非您计划在方法中更多地使用它,否则您不需要在那里设置变量.

此时,您可以轻松地向ActiveRel模型添加after_create回调,该回调将在from_node上执行 *** 作,from_node始终是您刚刚创建的用户.您可以从那里更新用户的属性.控制这种行为正是ActiveRel存在的原因.

我可能还会再修改一下.首先将您的Facebook内容移动到模块中.它将使您的用户模型更清洁,更专注.

# models/concerns/facebook.rbmodule Facebook  extend ActiveSupport::Concern  def facebook    @facebook ||= Koala::Facebook::API.new(oauth_token)    block_given? ? yIEld(@facebook) : @facebook      rescue Koala::Facebook::APIError => e      logger.info e.to_s      nil  end  def frIEnds_count    facebook { |fb| fb.get_connection("me",summary: {}) }  endend# Now back in User...class User  include Neo4j::ActiveNode  include Facebook  # more code...end

你的模特很容易成为这些凌乱的抓包.很多博客会鼓励这一点.战斗的冲动!

这应该是一个好的开始.如果您有任何问题或者我搞砸了什么问题,请告诉我,有很多代码,我可能需要澄清或调整一些代码.但希望它有所帮助.

总结

以上是内存溢出为你收集整理的ruby-on-rails – 使用after_save在Neo4J模型中创建关系全部内容,希望文章能够帮你解决ruby-on-rails – 使用after_save在Neo4J模型中创建关系所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1286756.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-09
下一篇2022-06-09

发表评论

登录后才能评论

评论列表(0条)

    保存