【问题标题】:One method for two models. How to pass name of model as variable to controller?两种模型的一种方法。如何将模型名称作为变量传递给控制器​​?
【发布时间】:2015-12-16 16:43:21
【问题描述】:

我在两个不同的控制器(帖子和板)中有两种方法。它们几乎相同。区别只是模型-实例-关联名称。要干这个我想在模块中编写方法,但是如何在 Post 和 Board 之间共享它?

def init_post_comments
    @user = current_user
    a = @user.posts.pluck(:id) # not very nice...
    b=params[:post_ids] ||= []
    b = b.map(&:to_i)
    follow = b - a
    unfollow = a - b
    follow.each do |id| # checkbox just checked
      @post = Post.find_by_id(id)
      if @post.users.empty?
        @post.update_attribute(:new_follow, true)
      end
      @user.posts << @post
    end
    unfollow.each do |id| # if checkbox was unchecked
      @post = Post.find_by_id(id)
      remove_post_from_user(@post)# here we destroy association
    end
    if follow.size > 0
      get_post_comments_data
    end

    redirect_to :back

  end

更新好的,如果我将方法转移到模型的关注点,我应该如何在这里处理关联?在这里@user.posts.pluck(:id) 和这里@user.boards.pluck(:id) 用我可以替换帖子和板,以便它可以与它们一起使用?

【问题讨论】:

  • 你能把你的问题说得更具体一些吗?什么是董事会?具体来说,您想要完成什么?
  • 您可以在这两个类中包含该模块,然后您可以在任一类的实例上调用它。
  • @brito 如果在我的代码中您将 Post-@post-posts 替换为 Board-@board-boards,这将是相同的方法,但适用于另一个模型。现在我在两个不同的控制器 PostsController 和 BoardsController 中编写了两次代码。但没关系,它可以是 Foo 和 Bar。
  • @MaxWilliams 好的,但是这个方法对于共享模块应该是什么样子的?这是一个问题。
  • 这大部分是业务逻辑,应该放在模型中,如果是通过模块共享的方法,如果你想要类,可以参考self

标签: ruby-on-rails associations relationship activesupport-concern


【解决方案1】:

所以,我做到了!我不知道这是否正确,但我 DRY 这段代码。

两个控制器:

posts_controller.rb

def init_comments
    if Post.comments_manipulator(current_user, params[:post_ids] ||= []) > 0
      @posts = Post.new_post_to_follow  
      code = []
      @posts.each do |post|
        group = post.group
        code = code_constructor('API.call')
      end
      Post.comments_init(get_request(code), @posts)
    end
    redirect_to :back
  end

boards_controller.rb

def init_comments
    if Board.comments_manipulator(current_user, params[:board_ids] ||= []) > 0
      @boards = Board.new_board_to_follow
      code = []
      @boards.each do |board|# подготовка запроса
        group = board.group
        code = code_constructor('API.call')
      end
      Board.comments_init(get_request(code), @boards)
    end
    redirect_to :back
  end

如您所见,它们完全相同。 在型号 board.rbpost.rb - include CommentsInitializer

models\concerns

module CommentsInitializer
  extend ActiveSupport::Concern

module ClassMethods
  def comments_manipulator(user, ids)
    relationship = self.name.downcase + 's'
    a = user.send(relationship).pluck(:id)
    b = ids.map(&:to_i)
    follow = b - a
    unfollow = a - b
    follow.each do |id| # start to follow newly checked obj
      @obj = self.find_by_id(id)
      if @obj.users.empty?
        @obj.update_attribute(:new_follow, true)
      end
      user.send(relationship) << @obj
    end

    unfollow.each do |id| # remove from following
      @obj = self.find_by_id(id)
      remove_assoc_from_user(@obj, user)#destroy relation with current user
    end

    follow.size
  end

  def comments_init(comments, objs)
    i = 0
    objs.each do |obj| # updating comments data
      if comments[i]['count'] == 0
        obj.update(new_follow: false)
      else
        obj.update(new_follow: false, last_comment_id: comments[i]['items'][0]['id'])
      end
      i += 1
    end
  end

  def remove_assoc_from_user(obj, user)
    user = user.id
    if user
      obj.users.delete(user)
    end
  end
end

我的代码有效。如果您知道如何使它更好,请回答!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多