2014-01-26 2 views
0

У меня проблема. Я разрабатываю приложение Rails и столкнулся с проблемой, которую я не могу исправить.Rails 2-сторонняя ассоциация не работает

На данный момент мое приложение позволяет пользователям вводить данные о продукте в базу данных (хранится в «таблице продуктов»). Вот схема для используемой базы данных.

ActiveRecord::Schema.define(version: 20140126073333) do 

    create_table "ijns", force: true do |t| 
    t.integer "number" 
    t.integer "product_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.integer "quantity" 
    end 

    add_index "ijns", ["number"], name: "index_ijns_on_number" 

    create_table "products", force: true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.integer "ijn_id" 
    end 

    add_index "products", ["name"], name: "index_products_on_name" 

end 

Существует еще одна таблица под названием «ijns», которая присваивает каждому идентификатору уникальный идентификатор. Этот ijn не был сделан первичным ключом намеренно, так как я не хочу, чтобы он был автоматически увеличиваемым значением.

Соотношение ч/б и IJN Товар:

продукт, has_many ijns и IJN belongs_to одного продукта.

Вот моя модель продукта

class Product < ActiveRecord::Base 
    has_many :ijns 
    validates :name, presence: true, length: { minimum: 10 }, uniqueness: true 
end 

модели для IJN.

class Ijn < ActiveRecord::Base 
    belongs_to :product 

    validates :number, presence: true, uniqueness: true, length: { is: 4 }, numericality: { only_integer: true } 
    validates :product_id, presence: true 
    validates :quantity, presence: true 
end 

Я смог получить ассоциацию со стороны IJN, то есть, я могу получить доступ к полям модели продукта, используя что-то вроде:

@ijn.product.name 

Но я не чтобы получить доступ к полю 'number' таблицы ijns из модели продукта

Надеюсь, я ясно объяснил свою проблему. Пожалуйста, дайте мне знать, если требуется дополнительная информация. С нетерпением жду некоторых ответов! :)

первый Edit:

Когда я смотрю на моем столе "продукции в браузере базы данных sqlite3, столбец для ijn_id существует, но по какой-то причине нет записей. Вот скриншот:

Products Table in Database Browser

IJN table in Database Browser

+2

Что вы пробовали? Если вы напишете '@ product.ijns', что вы получите? «NoMethodError» или что-то еще? –

+0

Да, Робин, я получаю NoMethodError – vjrngn

ответ

0
puts Product.first.ijn.number 

Это должно работать в соответствии с тем, что вы хотите сделать.

+0

Эй, @murrekatt, я попробовал это, но опять же: «NoMethodError: undefined method' ijn »для # « – vjrngn

1

Проблема в том, что вы определили Producthas_many:ijns. Это конфликтует с продуктом, имеющим ijn_id, как у вас в вашей схеме.

Таким образом, при попытке сделать product.ijn вы получите сообщение об ошибке.

Edit:

Если продукт действительно имеет много ijns того ijn_id не имеет смысла для ActiveRecord и баз данных. Они понятия не имеют, на что он должен ссылаться. Я подозреваю, что вы хотите, чтобы он ссылался на последний ijn, присвоенный продукту.

В этом случае одним из решений было бы изменить атрибут на что-то вроде current_ijn_id. Вам придется вручную назначать значение каждый раз, когда вам нужно его обновить.

Альтернативно вы можете сделать product.ijns.last. Проблема в том, что вам нужно будет гарантировать, что .last даст вам правильный ijn каждый раз. Например, это может не работать, если по какой-то причине вы откатываете продукт на старый ijn.

+0

Да, это то, о чем я думал .. Я пробовал делать продукт .ijn_id .. это тоже не работает .. ОК .. что вы предлагаете мне сделать, чтобы исправить это? Мне нужен двухсторонний доступ к таблицам. Ijn.product.name работает. Мне нужно «product.ijn.number». – vjrngn

+0

Соображайте ассоциации. Таким образом, у «Продукта» есть один или несколько «Ijn's?»? Если один, измените 'has_many' на' has_one'. Основы ассоциации ActiveRecord: http://guides.rubyonrails.org/association_basics.html – jcm

+0

Хорошо, позвольте мне просто кое-что прояснить. Экземпляр модели продукта может иметь только один IJN, а экземпляр модели IJN может иметь только один продукт.НО, одному и тому же продукту также может быть назначен другой IJN в течение жизненного цикла приложения. Разве это не означает, что продукт has_many IJN? – vjrngn

1

Кажется, что вы делаете это гораздо сложнее, чем вам нужно:


Таблица

Ваш ijn номер как SKU (уникальный идентификатор для вашей системы) не так ли? Как это атрибут продукта, почему вы не просто поставить его в таблице продуктов:

#products table 
id | ijn | name | created_at | updated_at 

Это сразу исключает требование дополнительной таблицы (сохраняет запросы тоже)


Extra

Если вы хотите вызвать дополнительные данные для product, вам нужна таблица специально для этих данных

Для меня model представляет собой набор данных с определенной целью. Имея модель ijn «s не constutue это

#app/models/products.rb 
Class Product < ActiveRecord::Base 
    has_one :profile, class_name: "ProductProfile" 
end 

#app/models/product_profile.rb 
Class ProductProfile < ActiveRecord::Base 
    belongs_to :product 
end 

Это позволит вам назвать что-то вроде @product.profile.quantity или подобного

+0

Да, я так и думал. Вот почему Я принимал решение о структуре, которую должен выполнить мой db, я решил поместить свои продукты в отдельную таблицу, потому что это позволяет масштабировать мое приложение в случае, когда мне нужно добавить больше атрибутов в мою модель продукта ... Это было в основном причиной Я использовал две отдельные таблицы. Кроме того, поскольку продукты будут постоянно привязаны к новым уникальным значениям IJN через жизненный цикл приложений, лучше поместить его в свою собственную таблицу. – vjrngn

0

спасибо вам за вашу помощь ... Я сделал еще некоторое чтение и нашел мое решение .. Для отношений от одного до многих, как и у меня, вам нужно только указать «идентификатор» ссылочной таблицы с одной стороны, то есть, включая столбец «product_id» в таблице «ijn». Я удалил столбец «ijn_id» в таблице «products» и включил одну строку кода в мой «ProductController». Вот оно:

... 
def show 
    @product = Product.find(params[:id]) 
    #getting the related IJN 
    @ijn = Ijn.find(:all, :conditions => ['product_id = ?',@product]) 
end 

... 

Теперь, по мнению, связанное название продукта может быть ссылка просто делать

<% @ijn.map do |i| %> 
    <tr> 
     <td><%=i.number %></td> 
     <td><%= i.quantity %></td> 
     <td><%= i.name %></td> #this returs the assocaiated product name 
     <td><%= Date::MONTHNAMES[i.product.created_at.month] %></td> 
     <td>placeholder</td> 
     <td>placeholder</td> 
    </tr> 
<% end %> 

который возвращает список названий продуктов и связанных с ними IJNs. Я не добавил никакого стиля в свой код выше.

Я надеюсь, что это поможет кому-то другому, столкнувшись с аналогичной проблемой.

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