2015-07-03 49 views
0

兩個參考ID中只有一個被設置在我的一個表中。Rails - 如何一次記錄兩個參考ID

模式

enter image description here


模式

tech.rb

class Tech < ActiveRecord::Base 
    has_many :services 
end 

service_menu

class ServiceMenu < ActiveRecord::Base 
    has_many :services 
end 

service.rb

class Service < ActiveRecord::Base 
    belongs_to :tech 
    belongs_to :service_menu 
end 

控制器

services_controller.rb

def new 
    @service = current_tech.services.build 
end 

def create 
    @service = current_tech.services.build(service_params) 

    respond_to do |format| 
     if @service.save 
     format.html { redirect_to @service, notice: 'Service was successfully created.' } 
     format.json { render :show, status: :created, location: @service } 
     else 
     format.html { render :new } 
     format.json { render json: @service.errors, status: :unprocessable_entity } 
     end 
    end 
end 

private 

def service_params 
    params.require(:service).permit(:name) 
end 

查看

<%= simple_form_for @service do |f| %> 
    <div class="field"> 
    <%= f.label "Select service category" %> 
    <br> 

    <%= collection_select(:service, :name, ServiceMenu.all, :name, :name, {:prompt => true }) %> 
    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

每當我創建一個新的服務,只有tech_id記錄,但不是service_menu_id。 如何創建一項新的服務,將服務表同時記錄tech和service_menu ID?

任何幫助表示讚賞。

編輯7/3 2:55 PM EST

@顏菊方法起初並不爲我工作,但現在它。起初,我沒有正確引用services table中的service_menu_id。前

services分貝:

| Field   | Type   | Null | Key | Default | Extra   | 
+-----------------+--------------+------+-----+---------+----------------+ 
| id    | int(11)  | NO | PRI | NULL | auto_increment | 
| name   | varchar(255) | YES |  | NULL |    | 
| tech_id   | int(11)  | YES | MUL | NULL |    | 
| service_menu_id | int(11)  | YES |  | NULL |    | 
| created_at  | datetime  | NO |  | NULL |    | 
| updated_at  | datetime  | NO |  | NULL |    | 
+-----------------+--------------+------+-----+---------+----------------+ 

原因之前,不工作是有是KEY欄下沒有MUL值。

services現在DB:

| Field   | Type   | Null | Key | Default | Extra   | 
+-----------------+--------------+------+-----+---------+----------------+ 
| id    | int(11)  | NO | PRI | NULL | auto_increment | 
| name   | varchar(255) | YES |  | NULL |    | 
| tech_id   | int(11)  | YES | MUL | NULL |    | 
| service_menu_id | int(11)  | YES | MUL | NULL |    | 
| created_at  | datetime  | NO |  | NULL |    | 
| updated_at  | datetime  | NO |  | NULL |    | 
+-----------------+--------------+------+-----+---------+----------------+ 

這也讓我在services分貝刪除name列,因爲它不再需要。

感謝所有回覆。

回答

1

我沒有測試代碼,但這可能有效。

首先,更改您的視圖設置service_menu_id

<%= collection_select(:service, :service_menu_id, ServiceMenu.all, :id, :name, {:prompt => true }) %> 

其次,在你的控制器,讓service_menu_id經過:

def service_params 
    params.require(:service).permit(:service_menu_id) 
end 

然後,當你建立你的服務, service_menu_id將成功通過。

+0

你的方法記錄了service_menu_id到表中,但現在我的':name'列條目產生'null'。請指教。謝謝。 –

+0

您需要設置**名稱**的服務?然後只需添加** <%= f。text_field:name%> **在你的表單中。 ** collection_select **用於設置service_menu。 –

+0

經過進一步審查,您的方法奏效。請在我的帖子末尾看到我的編輯。非常感謝! :) –

1

您需要has_many :through關係添加到您的機型:

tech.rb

class Tech < ActiveRecord::Base 
    has_many :services 
    has_many :service_menus, through: :services 
end 

service_menu.rb

class ServiceMenu < ActiveRecord::Base 
    has_many :services 
    has_many :techs, through: :services 
end 

service.rb

class Service < ActiveRecord::Base 
    belongs_to :tech 
    belongs_to :service_menu 
end 

一旦你這樣做了,Active Record會負責你的連接模型(Service)管家。您可以在Rails控制檯中演示此操作:

>> tech = Tech.create(name: "bar") 
    (0.2ms) begin transaction 
    SQL (0.4ms) INSERT INTO "techs" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "bar"], ["created_at", "2015-07-03 23:30:26.893615"], ["updated_at", "2015-07-03 23:30:26.893615"]] 
    (10.7ms) commit transaction 
=> #<Tech id: 4, name: "bar", created_at: "2015-07-03 23:30:26", updated_at: "2015-07-03 23:30:26"> 
>> tech.service_menus << ServiceMenu.create(name: "baz") 
    (0.1ms) begin transaction 
    SQL (0.4ms) INSERT INTO "service_menus" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "baz"], ["created_at", "2015-07-03 23:31:21.045841"], ["updated_at", "2015-07-03 23:31:21.045841"]] 
    (18.9ms) commit transaction 
    (0.1ms) begin transaction 
    SQL (0.5ms) INSERT INTO "services" ("tech_id", "service_menu_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["tech_id", 4], ["service_menu_id", 4], ["created_at", "2015-07-03 23:31:21.072932"], ["updated_at", "2015-07-03 23:31:21.072932"]] 
    (33.1ms) commit transaction 
    ServiceMenu Load (0.3ms) SELECT "service_menus".* FROM "service_menus" INNER JOIN "services" ON "service_menus"."id" = "services"."service_menu_id" WHERE "services"."tech_id" = ? [["tech_id", 4]] 
=> #<ActiveRecord::Associations::CollectionProxy [#<ServiceMenu id: 4, name: "baz", created_at: "2015-07-03 23:31:21", updated_at: "2015-07-03 23:31:21">]> 
>> Service.first 
    Service Load (0.4ms) SELECT "services".* FROM "services" ORDER BY "services"."id" ASC LIMIT 1 
=> #<Service id: 2, tech_id: 4, service_menu_id: 4, created_at: "2015-07-03 23:31:21", updated_at: "2015-07-03 23:31:21">` 
+0

感謝您的答覆。我已經完成了你的建議,重新啓動了服務器,但遇到了service_menu_id沒有被記錄的相同症狀。 –

+0

當您在控制檯中創建實例時會發生什麼?如果這可行,但你的代碼不行,我會看@Pavan的回答,以獲得對你的控制器和視圖的建議。 –

+0

感謝您的評論。上面列出了與此功能有關的所有內容。我不確定如何在控制檯內建立這種關係。 Pavan的方法涉及手動輸入「:name」值,這是禁止的,因爲這些是由管理員輸入的預定義值。 –

0

您需要進行以下更改。

service_menu_id加入您的servuce_params。這樣

<%= simple_form_for @service do |f| %> 
    <div class="field"> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 
    </div> 
    <div class="field"> 
    <%= f.label "Select service category" %> 
    <br> 

    <%= collection_select(:service, :service_menu_id, ServiceMenu.all, :name, :name, {:prompt => true }) %> 
    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 
+0

謝謝您的回覆。來自'collection_select'的名字需要記錄到db中,而不是'f.text_field'中的':name'值。每次我創建一個新的'service'時'service_menu_id'都會返回一個值'0'。 –

0

def service_params 
    params.require(:service).permit(:name, :service_menu_id) 
end 

,並更改您的視圖代碼,如果你使用postrgesql,你可以在1.6 Composite Types閱讀本ActiveRecord documentation和使用composite types爲你的任務。

例如:

CREATE TYPE full_service_id AS 
(
    tech_id INTEGER, 
    service_menu_id_ INTEGER 
); 

# db/migrate/20140207133952_create_services.rb 
execute <<-SQL 
CREATE TYPE full_service_id AS 
    (
     tech_id INTEGER, 
     service_menu_id_ INTEGER 
    ); 
SQL 
create_table :services do |t| 
    t.column full_service_id 
end 

# app/models/service.rb 
class Service < ActiveRecord::Base 
    belongs_to :tech, foreign_key: 'full_service_id.tech_id' 
    belongs_to :service_menu, foreign_key: 'full_service_id.service_menu_id_' 
end 

# Usage 
Service.create full_service_id: "#{tech_id},#{service_menu_id_}" 
service = Service.first 
service.full_service_id # => "(1,1)" 
service.full_service_id = "(2,2)" 
service.save! 
+0

感謝您的評論。我爲這個測試應用程序使用sqlite,但我的主要是mysql。 –