如何在 Rails 中建立员工-公司关系?

如何解决如何在 Rails 中建立员工-公司关系?

我正在尝试在 Ruby on Rails 上创建一个工作板。我正在使用 devise 来处理帐户,并且我有一个 Employee(设备用户)和 Company 模型。

在这个挑战中,当有人以员工身份创建帐户时,我必须检查公司域是否已经存在(域是从员工电子邮件提取的),如果不存在,则必须将员工重定向到公司注册页面。此外,第一位员工将成为公司的管理员

问题是,那之间怎么做一个合适的关系呢?如果我彼此使用belongs_to 关系,则不可能在没有公司的情况下创建员工,反之亦然。如果我不这样做,以后就无法访问某些 ID 以建立正确的关系。更糟糕的是,稍后我需要为招聘广告创建一个 JobAd 模型,它应该属于公司和员工。那么,有没有办法在没有“员工没有公司,反之亦然”问题的情况下实现这一点?

这是我的 schema.rb

ActiveRecord::Schema.define(version: 2021_02_23_032327) do

  create_table "applicants",force: :cascade do |t|
    t.string "email",default: "",null: false
    t.string "encrypted_password",null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at",precision: 6,null: false
    t.datetime "updated_at",null: false
    t.index ["email"],name: "index_applicants_on_email",unique: true
    t.index ["reset_password_token"],name: "index_applicants_on_reset_password_token",unique: true
  end

  create_table "companies",force: :cascade do |t|
    t.string "name"
    t.string "logo"
    t.string "address"
    t.string "cnpj"
    t.string "site"
    t.string "social_media"
    t.string "domain"
    t.integer "employee_id",null: false
    t.datetime "created_at",null: false
    t.index ["employee_id"],name: "index_companies_on_employee_id"
  end

  create_table "companies_employees",id: false,force: :cascade do |t|
    t.integer "employee_id",null: false
    t.integer "company_id",null: false
    t.index ["company_id","employee_id"],name: "index_companies_employees_on_company_id_and_employee_id"
    t.index ["employee_id","company_id"],name: "index_companies_employees_on_employee_id_and_company_id"
  end

  create_table "employees",name: "index_employees_on_email",name: "index_employees_on_reset_password_token",unique: true
  end

  create_table "job_ads",force: :cascade do |t|
    t.string "title"
    t.text "description"
    t.integer "salary_range"
    t.integer "level"
    t.date "mandatory_requirements"
    t.integer "total_vacancy"
    t.integer "company_id",null: false
    t.integer "employee_id",null: false
    t.index ["company_id"],name: "index_job_ads_on_company_id"
    t.index ["employee_id"],name: "index_job_ads_on_employee_id"
  end

  add_foreign_key "companies","employees"
  add_foreign_key "job_ads","companies"
  add_foreign_key "job_ads","employees"
end

我现在正在尝试什么:

员工设备的 registration_controller.rb

class Employees::RegistrationsController < Devise::RegistrationsController
 
  def after_sign_up_path_for(resource)
    domain = resource.email.split('@').last
    if domain_is_free?(domain)
      @employee.save
      redirect_to new_company_path
      flash[:notice] = "Não identificamos o domínio #{domain},por favor registre-o"
    else
      redirect_to root_path
    end
  end

  def create
    @employee = Employee.new(employee_params)
    if @employee.save
      sign_in(@employee)
      after_sign_up_path_for(@employee)
    else
      render :new
    end
  end

  protected

  def domain_is_free?(employee_mail)
    !Company.exists?(['domain LIKE ?',"%#{employee_mail.split('@').last}%"])
  end 

  def employee_params
    params.require(:employee)
        .permit(:email,:password,:password_confirmation)
  end

公司.rb

class Company < ApplicationRecord
    belongs_to :employee
    has_many :employees
    has_many :job_ads    
end

员工.rb

class Employee < ApplicationRecord
  
  devise :database_authenticatable,:registerable,:recoverable,:rememberable,:validatable
  belongs_to :company,optional: true                  
        
end

rspec 测试

    require 'rails_helper'

feature 'employee creates an account' do
  scenario 'and is the first to register a domain' do
    visit root_path
    click_on 'Employee registration'

    within('form') do
      fill_in 'Email',with: 'roger@jobs.com'
      fill_in 'Password',with: '123456'
      fill_in 'Password confirmation',with: '123456'
      click_on 'Sign up'
    end

    expect(current_path).to eq new_company_path
    expect(page).to have_content 'There is no company named jobs,please register it'  
    expect(page).to have_content 'Register Company'
  end

最后是错误信息

Failure/Error:
   params.require(:company)
         .permit(:name,:logo,:address,:cnpj,:site,:social_media,:domain).merge(employee_id: current_employee.id)
 
 ActionController::ParameterMissing:
   param is missing or the value is empty: company
   Did you mean?  controller
                  action

解决方法

我认为您对这里的关联感到困惑,请尝试从 belongs_to :employee 文件中删除 company.rb

所以belongs_to 的意思是模型A 的一个实例属于模型B 的一个实例。这意味着没有B 的实例就不能存在A 的实例(例如,没有作者就不能存在Book)。查看此link了解更多信息!

此外,如果您希望员工成为公司的管理员,请将employee.rb 中的admin 字段添加为布尔值。

,

我不确定我是否理解了所有内容...

  1. 当您定义 belongs_to 关系时,您必须提供该表的外键。在 employee.rb 中,您编写 ruby belongs_to :company,optional: true 但不要将 company_id 字段添加到 employees 表中。 ?
  create_table "employees",force: :cascade do |t|
    t.string "email",default: "",null: false
    t.string "encrypted_password",null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at",precision: 6,null: false
    t.datetime "updated_at",null: false
    t.index ["email"],name: "index_employees_on_email",unique: true
    t.index ["reset_password_token"],name: "index_employees_on_reset_password_token",unique: true
  end
class Employee < ApplicationRecord
  
  devise :database_authenticatable,:registerable,:recoverable,:rememberable,:validatable
  belongs_to :company,optional: true                  
        
end

也许您只需要这个 has_one

  1. 如果你只是使用会怎样
@employee.create_company(company_params)

在这种情况下,您不必使用参数传递 employee_id。但是,您应该再次向Employees 表添加外键或替换为has_one :company 模型中的Employee

  1. 您可以尝试同时创建 employeecompany

accepts_nested_attributes_for :company 添加到 Employee 模型,然后在控制器中您可以调用如下代码:

def create
  ...
   @employee.create(employee_params)
  ...
end

def employee_params
    params.require(:employee)
          .permit(:email,:password,:password_confirmation,company_attributes: [:name,:logo,:address,:cnpj,:site,:social_media,:domain])
end

但它也只有在您将 company_id 字段添加到 Employee 表时才有效。无论如何,您可以反之亦然。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?