2015-12-16 79 views
2

我正在爲應用程序設置我的rails關聯,我不確定我的關聯對我的用例是否正確。用例是:產品可以由用戶添加一次。一旦創建,其他用戶就可以將相同的產品添加到應用程序中自己的「供稿」中。我希望能夠做到User.products列出所有的用戶產品。對於產品,我希望能夠像Product.where(id: 2).users那樣列出所有已添加產品的用戶。我目前正在使用has_and_belongs_to_many關聯,但我認爲這對於我想實現的目標是不正確的?Rails必須和屬於許多正確的鋼軌關聯?

用戶模式:has_and_belongs_to_many :products

產品型號:has_and_belongs_to_many :users

add_index "products_users", ["product_id"], name: "index_products_users_on_product_id" 
add_index "products_users", ["user_id"], name: "index_products_users_on_user_id" 
+0

是的,你正在做的是正確的,只是索引應該是爲了兩者,而不是單獨的'add_index:products_users,[:product_id,:user_id]' – jvnill

+0

爲什麼你認爲這是不正確的?此外,您是否試圖存儲關於用戶與產品的每個關聯的信息? –

+0

我從來沒有很好的協會。只是一種直覺,我想要正確。我想是這樣。我試圖實現的是類似於Pinterest的用戶添加圖像的功能,一旦添加圖像出現在其Feed中,其他用戶也可以添加圖像並將其從自己的Feed中移除。按照jvnill的說法, –

回答

2

這樣做:

#app/models/user.rb 
class User < ActiveRecord::Base 
    has_many :created_products, class_name: "Product", foreign_key: :user_id    #-> created product 
    has_and_belongs_to_many :products #-> list of products 
end 

#app/models/product.rb 
class Product < ActiveRecord::Base 
    belongs_to :user     #-> created the product 
    has_and_belongs_to_many :users #-> list of users 
end 

你需要的appropriate foreign_key添加到您的User模型(user_idProduct型號爲belongs_to :user協會) -

enter image description here

-

如果您的has_and_belongs_to_many關係已經正常工作,則上述內容應該足夠。

如果沒有,你需要查找this documentation,看看它是如何工作,然後創建一個連接表稱爲products_users(與適當的數據填充):

$ rails g migration CreateProductsUsers 

#db/migrate/create_products_users______.rb 
class CreateProductsUsers < ActiveRecord::Migration 
    def change 
     create_table :products_users, id: false do |t| 
     t.references :product 
     t.references :user 
     end 
    end 
end 

$ rake db:migrate 

它可以讓你爲用戶創建一個產品(IE的Product對象將與創建它的用戶有直接關聯)。 ProductUser型號也將加入habtm關係。


在你的控制器,你可以使用以下命令:

#config/routes.rb 
resources :products #-> url.com/products 
scope "profile" do 
    resources :products, only: :index #-> url.com/profile/products 
end 

這將允許您使用以下:

#app/controllers/products_controller.rb 
class ProductsController < ApplicationController 
    before_action :product, only: :edit 

    def index 
     @products = current_user.products #-> if you're using Devise 
    end 

    def edit 
    @product = current_user.created_products.find params[:id] 
    end 

    def new 
    @product = current_user.created_products.new 
    end 

    def create 
    @product = current_user.created_products.new product_params 
    @product.save 
    end 

    private 

    def product 
    redirect_to root_path, notice: "This is not your product" unless current_user.products.exists? params[:id] 
    end 

    def product_params 
    params.require(:product).permit(:x, :y, :z) 
    end 
end 
+0

感謝您的徹底和周到的答案。我打算讓用戶能夠添加來自不同來源的多個產品,'has_one:product'仍然適用於這種情況嗎?除非我誤解用戶只能擁有一個產品? –

+0

「產品可以由用戶添加一次」我認爲這意味着用戶只能添加一個產品。如果情況並非如此,我將不得不改變我的觀點 –

+0

對不起選擇不好的詞。我的意思是產品只能添加一次(它必須是唯一的)。 –