Rails:如何只允许用户只申请一次工作?

时间:2014-09-18 01:51:05

标签: ruby-on-rails ruby devise

我正在创建一个工作板,我不想让用户选择两次申请同一份工作。我怎么能限制这个?

应用/视图/作业/ job.html.erb

<% if applied_to_this_job? %>
    <div class="alert" role="alert">You have already applied to this job!</div>
<% else %>
    <%= link_to 'Apply', new_job_application_path(@job) %>
<% end %>

应用/助手/ jobs_helper.rb

def applied_to_this_job?
    JobApplication.exists? user_id: current_user.id
end

显然这不起作用,因为它会检查此用户是否已申请任何工作。如何查看当前用户是否已应用于正在查看的作业。

另外,如何在控制器级别对此进行限制,以便用户无法转到job_application / new并转到表单。

3 个答案:

答案 0 :(得分:4)

您可以在控制器操作中使用before_filter

class JobsController < ActionController::Base

  before_filter :has_applied?, only: [new, create]

  ....

  private

    def has_applied?
      if JobApplication.where(user_id: :current_user.id, job_id: params[:job_id]).any?
        redirect_to :index, alert: "You have already applied"
      end
    end

end

这将允许用户访问/jobs/new并将申请发布到/jobs/create,除非他们已申请。如果已应用,则会将它们重定向到示例代码中的索引。

另外,正如另一个答案所指出的那样,传递工作ID也是明智之举。更新了上面的示例代码以反映。

答案 1 :(得分:1)

您需要检查并查看JobApplication对象是否适用于此@job尝试:

JobApplication.where(user_id:current_user.id,job_id:@ job.id).exists?

答案 2 :(得分:1)

虽然您接受的内容可行,但我认为这有点像表面层次的修复。

使用验证器确定用户是否可以实际创建另一个作业应用程序会更好。这将防止您的前端&#34;中的业务逻辑出现任何问题。视图

以下是我处理它的方式:

-

<强> UNIQ

#app/models/user.rb
class User < ActiveRecord::Base
  has_one :job_application
end

#app/models/job_application.rb
class JobApplication < ActiveRecord::Base
   belongs_to :user
   validates :user_id, uniquness: true
end

您可能还希望为数据库提供user_id列的uniq索引:

> $ rails g migration AddUniqueIndex

#config/db/add_unique_index.rb
class AddUniqueIndex < ActiveRecord::Migration
   def change
     add_index :job_applications, [:job_id, :user_id], unique: true
   end
end

这将为您提供高效的数据库级唯一性索引 - 这意味着如果您尝试添加超出允许的应用程序,它将无声地失败,或者返回错误。


<强>控制器

控制器的结构可以让您对job_application功能的可访问性不那么严格:

#app/views/jobs/job.html.erb
<% if current_user.has_applied?(params[:job_id]) %>
    <div class="alert" role="alert">You have already applied to this job!</div>
<% else %>
    <%= link_to 'Apply', new_job_application_path(@job) %>
<% end %>

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :job_applications

   def has_applied?(job_id)
     job_applications.find job_id
   end
end