【问题标题】:Trouble with `has_many through:` Relationship`has_many through:` 关系的问题
【发布时间】:2019-01-03 12:20:35
【问题描述】:

我正在设置用户、网站和标签模型,但不确定正确的关联?

这是一个 CRUD 应用程序,我希望允许用户在其中创建一个“网站”(本质上是一个书签)并能够向该网站添加一个“标签”,以便可以过滤网站。

我有三个表:UserWebsiteTag

我想,用户有很多网站,网站有很多标签,标签属于网站,一个用户通过网站有很多标签。

我已经设置了以下模型:

class User < ActiveRecord::Base
  has_many :websites
  has_many :tags, through: :websites
end

class Website < ActiveRecord::Base
  belongs_to :user
  has_many :tags
end

class Tag < ActiveRecord::Base
  belongs_to :website
end

我正在通过发布请求保存标签:

post '/websites' do
  if logged_in?
    if params[:content] == ""
      redirect to "/websites/new"
    else
      @website = current_user.websites.build(content: params[:content])
      binding.pry
      @tag = current_user.tags.build(content: params[:dropdown])
      if @website.save && @tag.save
        redirect to "/websites/#{@website.id}"
      else
        redirect to "/websites/new"
      end
    end
  else
    redirect to '/login'
  end
end

当我在binding.pry 检查params 时,它给了我预期的结果:

{content=>"tryingtoaddtag.com", "dropdown"=>"Clothing"}

我的期望是能够保存用户的实例,然后使用@user.tags 显示与该用户的网站关联的所有标签。我无法完全弄清楚我在哪里搞砸了。谢谢。

【问题讨论】:

  • 你从@user.tags得到什么?
  • 所以我创建了一个标签为Travel 的网站,当我进入pry 并输入Tag.last 时,它给了我预期的结果。但是User.all[0].tags 给了我一个空数组。我仔细检查了User.all[0] 是否为我提供了创建网站/标签的正确用户
  • 你可以试试User.first.tags.to_sql 看看它是否正确加入了sql中的表?
  • 所以这就是它返回的结果:"SELECT \"tags\".* FROM \"tags\" INNER JOIN \"websites\" ON \"tags\".\"website_id\" = \"网站\".\"id\" WHERE \"网站\".\"user_id\" = 1"
  • 你能试试current_user.tags.build(content: params[:dropdown], website: @website)吗?如果这不起作用,您可以先保存@website,然后在构建时传递网站 ID。

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


【解决方案1】:

阅读这个Article 然后试试这个:

class Tag < ActiveRecord::Base
  belongs_to :website
  delegate :user, :to => :website, :allow_nil => true
end

如果这不起作用。在User 模型中使用作用域与

def tags
 Tags.where(website_id: self.websites.pluck(:id))
end

【讨论】:

  • 还是没有运气。如果我使用连接,我不应该创建 tags 方法,但我应该这样做吗?
【解决方案2】:

考虑一个网站 has_many :tags

class User < ActiveRecord::Base
  has_many :websites

  def user_tags
    Tag.joins(:website).where(websites: {user_id:  self.id})
  end

end

class Website < ActiveRecord::Base
  belongs_to :user
  has_many :tags
end

class Tag < ActiveRecord::Base
  belongs_to :website
end

查询 -

user = User.first
user.user_tags

【讨论】:

    【解决方案3】:

    尝试以下,

    class User < ActiveRecord::Base
      has_many :websites 
    end
    
    class Website < ActiveRecord::Base
      belongs_to :user
      has_many :tags
    end
    
    class Tag < ActiveRecord::Base
      belongs_to :website
      scope :user_tags, ->(user) { joins(:website).where(websites: {user_id:  user}) }
    end
    

    查询看起来像,(@user 对象)

    Tag.user_tags(@user)
    

    【讨论】:

      猜你喜欢
      • 2015-07-03
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      相关资源
      最近更新 更多