属于多态路由的用户关联

Belongs to user association with polymorphic routing

我有一个小型应用程序,其中有市区和房产。每个市中心都有很多房产,每个 属性 都有一个市中心。

在我的控制器中,我设置了允许在市中心的保护伞下创建任何新属性的东西,但现在我决定将用户添加到组合中......我遇到的问题是现有用户承认拥有其创建的模型之一。

我现有的控制器相关方法如下。我在想通过添加 @property.user_id = current_user.id 来处理它。但是如果我然后 运行 a Property.last.user

我得到一个ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: users.property_id:

# GET /downtowns/1/properties/new
def new
  set_downtown
  @property = @downtown.properties.new
end

# POST /downtowns/1/properties
def create
  set_downtown
  @property = @downtown.properties.new(property_params)
  @property.user_id = current_user.id

  if @property.save
    redirect_to @downtown
  else
    render :new
  end
end

private

def set_downtown
  @downtown = Downtown.includes(:properties).find(params[:downtown_id])
end

在我的模型中

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :properties
  has_many :downtowns
end

class Property < ApplicationRecord
  belongs_to :downtown
  belongs_to :user

  has_one :user  
end

不知道我是否需要粘贴这个,但我的路线文件是

Rails.application.routes.draw do
  devise_for :users
  root :to => "downtowns#index"
  resources :cities

  resources :downtowns do
    resources :properties
  end
end

如果有人能看一看,我将不胜感激!非常感谢!

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: users.property_id

因为您在 Property 中有 has_one :user。这意味着 user 持有 Propertyid 作为 property_id.

PropertyUser#id 保持为 user_id

移除has_one :user

class Property < ApplicationRecord
  belongs_to :downtown
  belongs_to :user      # this table has user_id
end
class Property < ApplicationRecord
  belongs_to :downtown
  belongs_to :user
end

您想使用 belongs_to 关联,因为外键列在 this 模型上。 has_many 关联的反向始终是 belongs_to 关联。

如果您声明两个同名的关联,后一个关联将始终覆盖前一个。

您几乎从不需要(或不想)显式使用 _id= setter。请改用 user= setter。

before_action :set_downtown, only: [:new, :create, :index] # DRY

# POST /downtowns/1/properties
def create
  @property = @downtown.properties.new(property_params) do |p|
    p.user = current_user
  end
  if @property.save
    redirect_to @downtown
  else
    render :new
  end
end