Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 使用after_save在Neo4J模型中创建关系_Ruby On Rails_Facebook Graph Api_Neo4j_Koala Gem_Neo4j.rb - Fatal编程技术网

Ruby on rails 使用after_save在Neo4J模型中创建关系

Ruby on rails 使用after_save在Neo4J模型中创建关系,ruby-on-rails,facebook-graph-api,neo4j,koala-gem,neo4j.rb,Ruby On Rails,Facebook Graph Api,Neo4j,Koala Gem,Neo4j.rb,因此,我为这些问题看起来多么愚蠢而道歉。我是rails的新手,作为第一个任务,我还引入了Neo4J,因为它似乎最适合我开发这个项目 我将解释操作流程,然后展示一些示例代码。我现在正在尝试添加步骤3-5 用户通过FB登录 第一次登录将创建一个用户节点。如果用户存在,它只检索该用户+节点 创建用户节点后,将使用考拉gem访问FB Graph API 检索使用应用程序的每个朋友的好友列表 浏览每个朋友,并在两个用户之间添加双向友谊关系 因为3-5只需要在用户第一次加入时发生,所以我想我可以在保存后通过

因此,我为这些问题看起来多么愚蠢而道歉。我是rails的新手,作为第一个任务,我还引入了Neo4J,因为它似乎最适合我开发这个项目

我将解释操作流程,然后展示一些示例代码。我现在正在尝试添加步骤3-5

  • 用户通过FB登录
  • 第一次登录将创建一个用户节点。如果用户存在,它只检索该用户+节点
  • 创建用户节点后,将使用考拉gem访问FB Graph API
  • 检索使用应用程序的每个朋友的好友列表
  • 浏览每个朋友,并在两个用户之间添加双向友谊关系
  • 因为3-5只需要在用户第一次加入时发生,所以我想我可以在保存后通过与
    回调关联的方法来实现。这个逻辑有一个缺陷,因为我需要在某个时候用额外的属性更新用户,并且它会在保存后再次调用。我可以通过更新防止这种情况发生吗

    SessionController供参考

      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
    
    友谊网

      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\u user是节点

    如果您看到其他不好的代码实践,请让我知道


    提前:谢谢你的帮助@subvertallchris。我相信你会回答我的很多问题,比如这个问题。

    这是一个非常好的问题!我认为你在正确的轨道上,但有一些事情你可以改变

    首先,您需要调整
    的has\u many
    方法。您的关联始终需要终止于节点,而不是ActiveRel类,因此您需要将其重写为如下内容:

    有很多:都有,:朋友,模型类:'User',rel类:'friends'

    否则你会遇到一些问题

    <>你可能想考虑NY4J风格一致性来重新命名你的关系类型。我有很多不好的例子,如果我给了你不好的想法,我很抱歉
    FRIENDS\u与
    是一个更好的关系名称

    至于处理你的大问题,你可以做很多

    编辑
    回调后丢弃
    ,使用两种方法加载现有用户/创建新用户行为

    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
      end
    end
    
    
    class 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 stuff
    end
    
    你并没有把它当作一个论点,所以把它扔掉。此外,如果您知道只查找单个节点,请使用
    find\u by
    。我假设每个用户都有一个
    facebook\u 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?
      end
    end
    
    create\u friendsity
    方法应该返回true或false,因此只需让该方法的最后一条语句执行该操作,就可以返回它返回的任何内容。这很简单:

    def self.create_friendship(user, friend_node)
      Friendship.new(from_node: user, to_node: friend_node).save
    end
    
    create
    不会返回true或false,它会返回结果对象,因此将
    save
    链接到新对象将得到您想要的结果。您不需要在那里设置变量,除非您计划在方法中更多地使用它

    此时,您可以很容易地在您的ActiveRel模型中添加一个
    后创建
    回调,该回调将在
    上从\u node
    执行操作,该节点始终是您刚刚创建的用户。您可以随时更新用户的属性。控制这种行为正是ActiveRel存在的原因

    不过,我可能会再做一点。首先,将你的
    facebook
    内容移动到一个模块中。它将使您的用户模型更清晰、更专注

    # models/concerns/facebook.rb
    
    module 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", "friends", summary: {}) }
      end
    end
    
    # now back in User...
    
    class User
      include Neo4j::ActiveNode
      include Facebook
      # more code...
    end
    
    你的模特很容易变成这些乱七八糟的抓包。很多博客都会鼓励这一点。战胜冲动


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

    哈哈哈!你正在展望未来!这是一个很好的问题。给我几分钟时间把它打出来。另外,如果你需要帮助并且不想出于任何原因在这里发帖,请随时给我发电子邮件。我同时学习了Ruby、Rails和Neo4j,因为它也适合我的项目!好吧,没有什么会出错,但它仍然无法挽救这段关系。我想friend_节点可能是空的。我想看看它是否正确地找到了节点
    friend\u node=User.find\u by(uid:friend[“id”])
    有什么好方法可以检查我的模型中rails/ruby中的内容是否为空并在我的视图中打印出来?我会问你一些关于友谊类型的问题,可能是slack中的
    # models/concerns/facebook.rb
    
    module 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", "friends", summary: {}) }
      end
    end
    
    # now back in User...
    
    class User
      include Neo4j::ActiveNode
      include Facebook
      # more code...
    end