简体   繁体   中英

Rails 2 way association not functioning

I have a bit of a problem. I've been developing a Rails app and have ran into a problem that I'm not able to fix.

As of now, my app allows users to enter product details into the database (stored in a 'products table') Here's the schema for the database I'm using.

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

There's another table called 'ijns' that assigns a unique identifier to each product. This ijn has not been made a primary key intentionally as I don't want it to be an auto incremented value.

The relation b/w IJN and Product is:

A product has_many ijns and An ijn belongs_to one product.

Here's my model for Product

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

Model for 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

I am able to get the association from the IJN side , ie, I'm able to access the fields of the product model by using something like:

@ijn.product.name

But I'm not able to access the 'number' field of the 'ijns' table from the product model

I hope I've been clear in explaining my problem. Please do let me know if additional info is required. Eagerly awaiting some replies! :)

1st Edit:

When i look at my 'products' table in the sqlite3 database browser, the column for ijn_id exists, but for some reason there are no entries. Here's a screenshot :

数据库浏览器中的产品表

数据库浏览器中的IJN表

The problem is that you've defined a Product has_many :ijns . This conflicts with a product having an ijn_id like you have in your schema.

Thus when you try to do product.ijn you get an error.

Edit:

If a product really has many ijns then ijn_id makes no sense to ActiveRecord and the database. They have no idea which ijn it is supposed to refer to. I suspect that you want it to refer to the last ijn assigned to the product.

In that case one solution would be to change the attribute to something like current_ijn_id . You will have to manually assign a value every time you need to update this.

Alternatively you could do product.ijns.last . The problem is you will need to ensure that .last will give you the correct ijn every time. It might not work for example, if for some reason you 'rollback' a product to an old ijn.

Seems you're making this more complicated than you need:


Table

Your ijn number is like an SKU (unique identifier for YOUR system) right? As it's an attribute of the product, why you don't just put it in the products table:

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

This immediately negates the requirement for an extra table (saves queries too)


Extra

If you want to call extra data for your product , you'll need a table specifically for that data

To me, a model is a collection of data with a specific purpose. Having a model for ijn 's does not constutue this

#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

This will allow you to call something like @product.profile.quantity or similar

puts Product.first.ijn.number

这应该根据你想要做的工作。

thank you so much for your help... I did some more reading and found my solution.. For a one to many relationship like mine, you only need to provide the 'id' of the referenced table on one side, ie, including the 'product_id' column in the 'ijn' table. I deleted the 'ijn_id' column in the 'products' table and included one line of code in my 'ProductsController'. Here it is:

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

...

Now, in the view, the associated product name can be reference by simply doing

<% @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 %>

Which returns the list of product names and associated IJNs. I haven't added any styling to my code above.

I hope this helps someone else who is facing a similar problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM