1

我是新來的鐵軌和我可能會丟失一些非常基本的位置:爲belongs_to的衆多車型的模型CRUD方法的Rails

用戶可以創建一個公司

爲兩個分支的接觸和分裂Branch.rb

class Branch < ApplicationRecord 
    belongs_to :company 
    has_many :contacts 
end 

Division.rb

class Division < ApplicationRecord 
    belongs_to :company 
    has_many :contacts 
end 

Contact.rb

class Contact < ApplicationRecord 
    belongs_to :branch 
    belongs_to :division 
end 

現在,用戶可以創建從分支頁面不存在division_id並能創造本司網頁中的聯繫人聯繫。

我定義我的routes.rb這樣的:

的routes.rb

resources :companies, :shallow => true do 
    get 'company_page' 
    resources :branches, :shallow => true do 
     get 'branch_page' 
     resources :contacts 
    end 
    resources :divisions, :shallow => true do 
     get 'division_page' 
     resources :contacts 
    end 
end 

其結果是,如果我創建從任一科或科接觸,它去接觸#創建方法。

在我contacts_controller.rb,我有:

def create 
    @newContact = Contact.new(contact_params) 
    id = @division = @branch = nil 
    isBranch = false 
    if params[:branch_id] != nil 
     isBranch = true 
     id = params[:branch_id] 
    else 
     isBranch = false 
     id = params[:division_id] 
    end 
    if isBranch 
     branch = Branch.find(id) 
     @newContact.branch = branch 
     @branch = branch 
    else 
     division = Division.find(id) 
     @newContact.division = division 
     @division = division 
    end 

    respond_to do |format| 
     if @newContact.save 
      format.js 
      format.html { render :nothing => true, :notice => 'Contact created successfully!' } 
      format.json { render json: @newContact, status: :created, location: @newContact } 
     else 
      format.html { render action: "new" } 
      format.json { render json: @newContact, status: :unprocessable_entity } 
     end 
    end  
end 

但在@newContact.save我已經面臨ActiveRecord Error

我確定我在這裏做的事情基本上非常錯誤,Rails以另一種我不知道的優雅方式處理這些事情。

+0

有什麼錯誤? – Anthony

+0

'在265ms內完成500次內部服務器錯誤(ActiveRecord:66。8ms)' – user122121

+0

我猜這個錯誤是因爲'聯繫'有兩個屬於關聯,但你只給它一個。 log/development.log中的錯誤是什麼? – Anthony

回答

3

由於@Anthony注意,你需要讓你的belongs_to協會可選:

# app/models/contact.rb 

class Contact < ApplicationRecord 
    belongs_to :branch, optional: true 
    belongs_to :division, optional: true 
end 

但另一個問題是,params[:division_id]params[:branch_id]始終爲零。這兩個密鑰都存在於[:contact]密鑰中。所以你得到的錯誤應該是ActiveRecord::RecordNotFound: Couldn't find Division with 'id'=

所有那些條件邏輯是不必要的。你可以用任何參數進行新的聯繫。另外,你應該使用Ruby約定來進行變量命名,這是snake_case而不是camelCase。

最後,我想你會想要將HTML請求重定向到分支或分區展示頁面,具體取決於關聯的內容。所以我添加了邏輯來做到這一點。

這裏的控制器#create行動的快速重構:

def create 
    @new_contact = Contact.new(contact_params) 

    if @new_contact.save 
     branch = @new_contact.branch 
     division = @new_contact.division 
     redirect_path = branch ? branch_path(branch) : division_path(division) 

     respond_to do |format| 
     format.js 
     format.html { redirect_to redirect_path, :notice => 'Contact created successfully!' } 
     format.json { render json: @new_contact, status: :created, location: @new_contact } 
     end 
    else 
     respond_to do |format| 
     format.html { render action: "new" } 
     format.json { render json: @new_contact, status: :unprocessable_entity } 
     end 
    end 
    end 

這證明了它的工作原理:

# spec/controllers/contacts_controller_spec.rb 

require 'rails_helper' 

RSpec.describe ContactsController, type: :controller do 
    let(:company) { Company.create!(name: 'Company Name') } 
    let(:division) { Division.create!(name: 'Division Name', company: company) } 
    let(:branch) { Branch.create!(name: 'Branch Name', company: company) } 

    describe '#create' do 
    context 'when created with a division id' do 
     let(:attributes) { {'division_id' => division.id, 'name' => 'Contact Name'} } 

     it 'creates a contact record and associates it with the division' do 
     expect(Contact.count).to eq(0) 
     post :create, params: {contact: attributes} 

     expect(Contact.count).to eq(1) 
     contact = Contact.first 
     expect(contact.division).to eq(division) 
     end 
    end 

    context 'when created with a branch id' do 
     let(:attributes) { {'branch_id' => branch.id, 'name' => 'Contact Name'} } 

     it 'creates a contact record and associates it with the branch' do 
     expect(Contact.count).to eq(0) 
     post :create, params: {contact: attributes} 

     expect(Contact.count).to eq(1) 
     contact = Contact.first 
     expect(contact.branch).to eq(branch) 
     end 
    end 
    end 
end 
+0

謝謝!這清除了我所有的疑慮。 – user122121