如何使rails资源ID对每个用户都不唯一?

时间:2014-01-21 16:13:53

标签: ruby-on-rails ruby-on-rails-4

假设我有一个rails应用程序供用户管理任务。 因此,当用户1创建任务时,它将具有以下URL:

user/task/1

现在另一个用户(#2)创建了一个新任务,它看起来像:

user/task/2

如果第一个用户将创建添加另一个用户,则它将具有数字3.依此类推。新任务不会反映用户拥有的任务量,而是反映数据库中存储的资源量。

我希望让每个用户创建任务,而不会看到系统中有多少任务。所以每个人都可以完成任务1,2,3 ..以及任务列表1,2,3 ..

我想一种方法是使用新的自定义ID并尝试将其放入URL中。我接近了吗?也许有一个很好的指导/更好的方式?

由于

2 个答案:

答案 0 :(得分:0)

如果我明白你想要完成什么,我会这样做:

在你的任务模型中,我会添加:

  1. belongs_to
  2. 添加user
  3. 添加名为user_specific_identifier
  4. 的整数列

    然后在控制器中确保查询范围以使用用户:

    def index
      @tasks = Task.where(user: current_user)
                   .where(user_specific_identifier: params[:id])
      # ...
    end
    

    您可以通过覆盖rails用作该模型的ID来使用to_param来帮助您的帮助程序正常工作。但是,如果ID不是唯一的,我还没有这样做。

    您可能想要结帐RailsCast #314 Pretty URLs with FriendlyId

答案 1 :(得分:0)

执行此操作的最简单方法是在用户记录上保留序号,当您需要新的任务ID时,该序号会增加。然后,您将此ID存储在任务上,并覆盖#to_param模型上的Task,以便Rails的URL帮助程序将其用于生成URL。

因此,您需要迁移:

add_column :users, :task_count, :integer
add_index  :users, :task_count, unique: true

add_column :tasks, :user_task_id, :integer
add_index  :tasks, :user_task_id, unique: true

然后在您的任务模型上添加before_create过滤器:

# Task
before_create :set_user_specific_id
def set_user_specific_id
  self.user_task_id = self.user.get_next_task_id!
end

def to_param
  self.user_task_id
end

# User
def get_next_task_id!
  # Atomic increment is used here to prevent race conditions from generating dupe IDs
  increment_counter :task_count
  reload
  self.task_count
end

现在,您可以使用user_task_path(user, task)之类的URL帮助程序生成使用特定于用户的ID的URL,而不是实际的行ID。你的发现者就像Task.where(user_id: params[:user_id], user_task_id: params[:id])