2015-07-03 2 views
0

В одной из моих таблиц устанавливается только один из двух идентификаторов ссылки.Rails - как записывать сразу два идентификатора ссылки

схема

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 в таблице сервисов?

Любая помощь приветствуется.

EDIT 7/3 2:55 вечера EST

@ Yen-Ju метод не работает для меня на первый, но теперь он делает. Сначала мне не удалось правильно указать service_menu_id в services table.

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 |    | 
+-----------------+--------------+------+-----+---------+----------------+ 

Причины не работаю, прежде чем это не было MUL значения при KEY колонки.

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 | MUL | NULL |    | 
| created_at  | datetime  | NO |  | NULL |    | 
| updated_at  | datetime  | NO |  | NULL |    | 
+-----------------+--------------+------+-----+---------+----------------+ 

Это также позволило мне не уронить name колонку в services дб, так как он больше не нужен.

Спасибо всем, кто ответил.

ответ

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 позаботится об обслуживании модели соединения (обслуживания) для вас. Это можно продемонстрировать в консоли 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.

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

И изменить ваш взгляд подобный код

<%= 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, а не в значение': name' из 'f.text_field'. Также 'service_menu_id' возвращает значение' 0' каждый раз, когда я создаю новую 'службу'. –

0

Если вы используете postrgesql, вы можете прочитать в ActiveRecord documentation1.6 Composite Types и использовать 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. –

Смежные вопросы