【问题标题】:rails active record query for 2 attributes listed togetherrails活动记录查询一起列出的2个属性
【发布时间】:2015-09-16 15:41:34
【问题描述】:

我想创建一个索引任务站点,并希望在同一个列表中列出所有任务(模型中的传入称为 execute_tasks,模型中的传出称为assigned_tasks),基于 created_at 混合。使用以下代码,我可以为传入和传出任务创建两个单独的列表,但看起来不太好。我什至不确定是否应该对模型、控制器或视图进行一些更改。

task.rb

belongs_to :assigner, class_name: "User"
belongs_to :executor, class_name: "User"

用户.rb

has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id"
has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id"

tasks.controller.rb

def index
  @user = current_user
  @assigned_tasks = @user.assigned_tasks.order("created_at DESC")
  @executed_tasks = @user.executed_tasks.order("created_at DESC")
end

tasks/index.html.erb

<div class= "container">
  <div class = "row">
    <% @assigned_tasks.each do |task| %>
      <% unless task.completed? %>
        <%= link_to user_task_path(id: task.id) do %> 
          <%= task.name %> 
        <% end %> 
        <%= task.content %>
        <%= task.executor.profile.first_name %>
      <% end %>
    <% end %>
    <br />
    <br />
    <% @executed_tasks.each do |task| %>
      <% unless task.completed? %>
        <%= link_to user_task_path(id: task.id) do %>
          <%= task.name %>
        <% end %>
        <%= task.content %>
        <%= task.assigner.profile.first_name %>
      <% end %> 
    <% end %>
  </div>
</div>

【问题讨论】:

    标签: ruby-on-rails database activerecord model-view-controller rails-activerecord


    【解决方案1】:

    在您的用户模型中添加一个方法,该方法将返回来自范围(assigned_tasks 和 excuted_tasks)的组合结果。

    用户.rb

      def tasks 
        tasks = assigned_tasks.uncompleted.order("created_at DESC")
        tasks += executed_tasks.uncompleted.order("created_at DESC")
        tasks.sort_by { |h| h[:created_at] }.reverse!
      end
    

    tasks.controller.rb

    def index
      @user = current_user
    end
    

    查看

    <% @user.tasks.each do |task| %>
      ..
      ..
    <% end %>
    

    【讨论】:

    • 我收到错误消息:nil:NilClass 的未定义方法 `[]'
    • 你能检查一下 current_user 是否为 nil 吗? ..分享更多信息
    • 我无法在 irb 中检查它,因为我使用的是 current_user,但我有 before_action:authenticate_user!在我的 tasks_controller 中执行所有操作并且完美运行。所以我确定我已经登录了,所以 current_user 不是 nil。
    • 对我来说真正奇怪的是,如果我使用控制台,我可以轻松调用 user.tasks,它会显示所有任务,包括分配和执行的任务。
    • 这应该很容易工作,分享你现有的代码,这样我也可以看看:)
    【解决方案2】:

    我会在User 上使用返回关系的组合查询方法。这样您就可以添加额外的范围,或者合并到一个联接中。

    class User < ActiveRecord::Base
      has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id"
      has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id"
    
      def associated_tasks
        Task.where('tasks.assigner_id = ? OR tasks.executer_id = ?', id, id)
      end
    end
    
    user = User.first
    tasks = user.associated_tasks
    

    或者,您可以在 Task 上创建一个范围:

    class Task < ActiveRecord::Base
      belongs_to :assigner, class_name: "User"
      belongs_to :executor, class_name: "User"
      scope :associated_with_user, (u) -> { where('tasks.assigner_id = ? OR tasks.executer_id = ?', u.id, u.id) }
    end
    
    user = User.first
    tasks = Task.associated_with_user(user)
    

    【讨论】:

      【解决方案3】:

      您可以从分配和执行的任务中创建一个数组,并按 created_at 对其进行排序。 类似的东西:

      tasks = []
      tasks << @assigned_tasks
      tasks << @expired_tasks
      @tasks = tasks.sort_by { |c| c[:created_at]}.reverse
      

      在你看来:

      <% @tasks.each do |task| %>
        ....
      <% end %>
      

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        也许您可以向用户模型添加一个方法。

        用户.rb

        def tasks
          Task.find_by_sql ["SELECT tasks.* FROM tasks WHERE  assigner_id = ? OR executor_id = ? order by created_at DESC", self.id, self.id]
        end
        

        您的控制器可能如下所示:

        def index
          @user = current_user
          @all_tasks = @user.tasks
          @assigned_tasks = @user.assigned_tasks.order("created_at DESC")
          @executed_tasks = @user.executed_tasks.order("created_at DESC")
        end
        

        然后您可以在视图中调用 user.tasks 并且数据库可以负责检索和排序记录...

        上面的语法没有经过全面测试,但希望能给你一些可以使用的东西。

        【讨论】:

        • 我的控制器会是什么样子?我还想稍后用 gem 添加分页。分页也必须在控制器中设置,我希望这个方法能兼容。
        • 我试了一下,得到了这个:undefined method `each' for nil:NilClass
        • 我再次尝试了它并且它正在工作,但我需要更多的东西,因为我想检查任务是否未完成。我为此使用范围并以这种方式工作:@executed_tasks =@user.executed_tasks.uncompleted.order("created_at DESC")
        猜你喜欢
        • 1970-01-01
        • 2013-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多