我正在创建一个工作板,我不想让用户选择两次申请同一份工作。我怎么能限制这个?
应用/视图/作业/ 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并转到表单。
答案 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