简体   繁体   English

Rails:活动记录协会

[英]Rails: Active Record Association

I'm banging my head against a Problem with AR Associations for 2 days now. 我为解决AR协会的问题而动摇了两天。 I know there is a easy solution to this but I can't figure out. 我知道有一个简单的解决方案,但我不知道。

I have two models Products and Users, that should be linked together. 我有两个模型“产品”和“用户”,应该链接在一起。 A Product should belong to a user and a user should have many products. 产品应属于用户,并且用户应拥有许多产品。 I didn't manage to set the user variable in my controller, so I went for a habtm association. 我没有设法在控制器中设置用户变量,所以我去了一个habtm关联。 Here are the models: 这些是模型:

User.rb User.rb

class User < ActiveRecord::Base
# Include default devise modules. Others available are:
#...

has_and_belongs_to_many :products

Product.rb Product.rb

class Product < ActiveRecord::Base
has_many :product_images, :dependent => :destroy
accepts_nested_attributes_for :product_images, :allow_destroy => :true
has_and_belongs_to_many :users

products_controller.rb products_controller.rb

class ProductsController < ApplicationController

def index
@products = Product.search(params[:search]).order(sort_column + ' ' + sort_direction).paginate(:per_page => 10, :page => params[:page])

respond_to do |format|
  format.html # index.html.erb
  format.json { render json: @products }
end
end

def new
@user = current_user
@product = Product.new#@user.products.build(params[:product])
@product.product_images.build
respond_to do |format|
  format.html # new.html.erb
  format.json { render json: @product }
end
end

def create
@user = current_user
@product =  @user.products.build(params[:product])#Product.new(params[:product])
    @product.product_images.build
    @user.products << @product

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

_form.html.erb _form.html.erb

<%= form_for @product, :html => {:multipart => true, :class => 'form-horizontal'} do |f| %>

schema.rb schema.rb

....
create_table "products_users", :id => false, :force => true do |t|
t.integer "product_id"
t.integer "user_id"
end
....

So, even I know, there should be a one-to-many association between user and product, this works out for me. 因此,即使我知道,用户与产品之间也应该存在一对多关联,这对我来说很有效。 In IRB, I can do this: 在IRB中,我可以这样做:

u = User.first
u.products

with the habtm association I can even do it viseversa: 通过habtm协会,我什至可以做到这一点:

p = Product.first
p.users

But I can't access the user attributes: 但是我无法访问用户属性:

p.users.username:

NoMethodError:   User Load (2.0ms)  SELECT "users".* FROM "users" INNER JOIN "products_users" ON "users"."id" = "products_users"."user_id" WHERE "products_users"."product_id" = 12

Could anybody be so nice to help me out of this? 有人能帮到我吗? What am I doing wrong? 我究竟做错了什么?

Thanks a lot! 非常感谢! Your help would save my weekend! 您的帮助将节省我的周末!

EDIT: Here's my controller action for the one-to-many relation: 编辑:这是我对一对多关系的控制器动作:

class ProductsController < ApplicationController

helper_method :sort_column, :sort_direction
def index
@products = Product.search(params[:search]).order(sort_column + ' ' + sort_direction).paginate(:per_page => 10, :page => params[:page])

respond_to do |format|
  format.html # index.html.erb
  format.json { render json: @products }
end

end 结束

def show @product = Product.find(params[:id]) @images = @product.product_images respond_to do |format| def show @product = Product.find(params [:id])@images = @ product.product_images response_do | format | format.html # show.html.erb format.json { render json: @product } end end format.html#show.html.erb format.json {渲染json:@product}结束

def new
@user = current_user
@product = Product.new#@user.products.build(params[:product])
@product.product_images.build
#3.times { @product.product_images.build }
respond_to do |format|
  format.html # new.html.erb
  format.json { render json: @product }
end
end


def edit
@product = Product.find(params[:id])
    @product.product_images.build
end


def create
@user = current_user
@product =  @user.products.build(params[:product])#Product.new(params[:product])
    @product.product_images.build


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


def update
@product = Product.find(params[:id])

respond_to do |format|
  if @product.update_attributes(params[:product])
    format.html { redirect_to @product, notice: 'Product was successfully updated.' }
    format.json { head :no_content }
  else
    format.html { render action: "edit" }
    format.json { render json: @product.errors, status: :unprocessable_entity }
  end
end
end


def destroy
 @product = Product.find(params[:id])
 @product.destroy

respond_to do |format|
  format.html { redirect_to products_url }
  format.json { head :no_content }
end
end

private
def sort_column
Product.column_names.include?(params[:sort]) ? params[:sort] : "created_at"
# params[:sort] || "created_at"
end

def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
# params[:direction] || "asc"
end
end

EDIT2: Schema.rb 编辑2:Schema.rb

create_table "products", :force => true do |t|
t.string   "title"
t.string   "description"
t.string   "testimonial"
t.decimal  "credits",       :precision => 3, :scale => 0
t.datetime "created_at",                                  :null => false
t.datetime "updated_at",                                  :null => false
t.decimal  "age"
t.string   "condition"
t.string   "product_image"
t.string   "image"
t.integer  "user_id"
end

create_table "users", :force => true do |t|
t.string   "email",                  :default => "", :null => false
t.string   "encrypted_password",     :default => "", :null => false
t.string   "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer  "sign_in_count",          :default => 0
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string   "current_sign_in_ip"
t.string   "last_sign_in_ip"
t.datetime "created_at",                             :null => false
t.datetime "updated_at",                             :null => false
t.string   "username"
t.integer  "product_id"
end

Don't use a has_and_belongs_to_many if you have a one-to-many relation. 如果您具有一对多关系,请不要使用has_and_belongs_to_many Creating and maintaining another table is adding too much complexity. 创建和维护另一个表会增加太多的复杂性。 My advice would be to figure out why you can't make the one-to-many relation working. 我的建议是弄清楚为什么您不能使一对多关系正常运行。

You should be able to make this work : 您应该能够完成这项工作:

class User < ActiveRecord::Base
  has_many :products #Plural
end


class Product < ActiveRecord::Base
  belongs_to :user #Singular
end

If it doesn't work, copy/paste your controller code that you use for one-to-many relation! 如果它不起作用,请复制/粘贴用于一对多关系的控制器代码!

Good luck 祝好运

Because Product has many users , p.users is an array-like object. 因为Product有许多usersp.users是一个类似数组的对象。 You need p.users[0].username . 您需要p.users[0].username

But why can't you make it a standard one-to-many association? 但是,为什么不能使它成为标准的一对多关联呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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