Model.find()调用其他模型

时间:2019-11-14 03:29:43

标签: ruby-on-rails rails-activerecord rails-models

我有3个模型用户,例如微型帖子

我关注了Michael Hartl的Ruby on Rails教程 https://rails-4-0.railstutorial.org/book

现在,我正在添加新功能,并试图添加一个点赞按钮,经过一些更改,现在我的微博删除按钮不起作用。

#micropost_controller   
def destroy
        Micropost.find(params[:id]).destroy
        redirect_to root_url
      end

#_micropost.html.erb
<%= link_to "delete", micropost, method: :delete,
                                   data: { confirm: "You sure?" },
                                   title: micropost.content %>

即使我正在调用Micropost.find Active Record在Likes表中搜索并给出错误为

ActiveRecord::StatementInvalid in MicropostsController#destroy
SQLite3::SQLException: no such column: likes.micropost_id: SELECT "likes".* FROM "likes" WHERE "likes"."micropost_id" = ?

当我尝试删除用户时,发生类似的事情。因此,基本上,无论我要调用的是哪种销毁,都将其重定向到类似模型的地方

PS:问题是我执行后开始

ActiveRecord::Base.connection.execute("BEGIN TRANSACTION; END;")

我刚获得BusyException: database is locked: commit transaction

模型

#like.rb
class Like < ApplicationRecord
    belongs_to :microposts, optional: true
    belongs_to :users, optional: true
    validates :src_user_id, presence: true
    validates :des_user_id, presence: true
    validates :post_id, presence: true
end


#micropost.rb
class Micropost < ActiveRecord::Base
  belongs_to :user
  default_scope -> { order('created_at DESC') }
  validates :content, presence: true, length: { maximum: 140 }
  validates :user_id, presence: true
  has_many :likes, dependent: :destroy

  # Returns microposts from the users being followed by the given user.
  def self.from_users_followed_by(user)
    followed_user_ids = "SELECT followed_id FROM relationships
                         WHERE follower_id = :user_id"
    where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
          user_id: user.id)
  end

  def self.search(search)
    where("content LIKE ?", "%#{search}%")
  end

end


#user.rb
class User < ActiveRecord::Base

  has_many :microposts, dependent: :destroy

  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id",
                                 class_name:  "Relationship",
                                 dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower

  has_many :likes, foreign_key: "src_user_id", dependent: :destroy
  has_many :liked_by_users, through: :likes, source: :likes

  scope :starts_with, -> (name) { where("name like ?", "#{Example User}%")}

  before_save { self.email = email.downcase }
  before_create :create_remember_token
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }, unless: Proc.new { |user| user.password.nil? }
  validates :password_confirmation, presence: true, unless: Proc.new { |user| user.password.nil? }
  validates :birthday, presence: true
  validate :email_verification, on: :update

end

2 个答案:

答案 0 :(得分:1)

正确的关联将是

#user.rb

has_many :microposts, dependent: :destroy
has_many :likes, through: :microposts, foreign_key: "post_id"


#micropost.rb
belongs_to :user
has_many :likes, dependent: :destroy, foreign_key: "post_id"


#like.rb
belongs_to :micropost, optional: true

此后,一切正常

答案 1 :(得分:1)

class User
  has_many :microposts, dependent: :destroy
   # You never have to specify foreign key for indirect assocations
  has_many :likes, through: :microposts
end

class Micropost
  belongs_to :user
  has_many :likes, dependent: :destroy, foreign_key: "post_id"
end


class Like
  # You must specify the foreign key if it cannot be derived from the name of the association
  # `belongs_to :micropost` will use micropost_id
  belongs_to :micropost, optional: true, foreign_key: "post_id"
  belongs_to :user # you have to add a `likes.user_id` column
end

尽管我真的会质疑您是否要对用户喜欢和微博喜欢使用相同的表/模型。实际上,这只会使事情变得复杂得多,最终您会得到一个包含大量空值的表。如果这是本书的一部分,我真的很想知道作者认为这是一个非常糟糕的设计。

您可以将其设置为:

# app/models/users/like.rb
# table name is users_likes
module Users
  class Like
    belongs_to :src_user, class_name: 'User', optional: false
    belongs_to :des_user, class_name: 'User', optional: false
  end
end

class User
   has_many :likes_as_src, 
     class_name: 'Users::Like',
     foreign_key: :src_user
   has_many :likes_as_des, 
     class_name: 'Users::Like',
     foreign_key: :src_user
end

# app/models/users/like.rb
# table name is microposts_likes
module Microposts
  class Like
    belongs_to :user, optional: false
    belongs_to :micropost, optional: false, foreign_key: 'post_id'
  end
end

class User
  has_many :micropost_likes, class_name: 'Microposts::Like'
  has_many :liked_microposts, through: :micropost_likes, source: :micropost
end

这为您提供了两个带有不可空外键和良好索引的简单联接表。这也使验证非常直接。