【问题标题】:Rails: Display user's liked post & own their posts on the same pageRails:显示用户喜欢的帖子并在同一页面上拥有他们的帖子
【发布时间】:2013-05-19 03:12:38
【问题描述】:

我对 Rails 还很陌生,而且我已经被这个问题困扰了几个小时。我正在尝试显示用户喜欢的帖子和用户的实际帖子。

使用我当前的代码,我收到此错误“未定义的方法 `title' for #”,它是从以下行中提取的:“”。

有没有人能解释一下我如何才能让它工作? (下面有更多代码)

def show
@user = User.find_by_username(params[:id])

if @user
    @posts = @user.posts.all + @user.likes.all
    render actions: :show
    @likes = @user.likes.all
else
    render file: 'public/404', status: 404, formats: [:html]
end
end

这是我的路线文件:

resources :likes, only: [:create, :destroy]
resources :posts

devise_scope :user do
  get 'register', to: 'devise/registrations#new'
  get 'edit', to: 'devise/registrations#edit'
  get 'login', to: 'devise/sessions#new'
  get 'logout', to: 'devise/sessions#destroy'
end

这是“显示”视图:

<% if @posts %>
  <% @posts.each do |post| %>
    <%= link_to post.title, post %>
  <% end %>
<% end %>

" display " 这是结果

<Post id: 11, title: "testing123", user_id: 2, created_at: "2013-05-18 19:25:45", updated_at: "2013-05-18 19:25:45"> #<Like id: 23, post_id: 10, user_id: 2, created_at: "2013-05-18 21:39:17", updated_at: "2013-05-18 21:39:17">

当我只使用它时它可以工作 -> @posts = @user.posts.all 但是当我使用它时问题就开始了 -> @posts = @user.posts.all + @user.likes.all

这给了我 "undefined method `title'" 消息..

【问题讨论】:

  • 您能发布您的路线文件吗?
  • @derek_duncan 刚刚在上面添加了我的路线文件(已编辑)
  • 你能不能也显示一下那条线在哪里?
  • @lis2 刚刚在上面编辑过
  • 奇怪,你能不能代替 显示 以确保你真的得到了帖子对象?

标签: ruby-on-rails ruby-on-rails-3.2


【解决方案1】:

您可能想在用户模型中添加一些东西...

class User < ActiveRecord::Base

  has_many :likes
  has_many :liked_posts, :through => :likes, :source => :post

  ...

end

然后,在您的控制器中,您可以这样做

@posts = @user.posts + @user.liked_posts 

【讨论】:

  • 哇这工作!仍然习惯于 rails 中的关联.. 谢谢!
  • 是的 - “来源”通常是令人困惑的部分。它是用于执行 :through 的连接模型中的“belongs_to”。在这种情况下,帖子关联是我们在不明确称其为“帖子”的情况下通过喜欢的方式(因为已经采取了)。
【解决方案2】:

我认为在活动记录中它会比使用 ruby​​ map 更快

@posts = Post.joins("left join likes on likes.post_id = posts.id").
where("posts.user_id ? OR likes.user_id = ?", @user.id, @user.id)

在后期模型中定义范围可能更好

scope :owned_or_liked_by, ->(user) { joins("left join likes on likes.post_id = posts.id").
where("posts.user_id ? OR likes.user_id = ?", user.id, user.id) }

然后你可以使用

@posts = Post.owned_or_liked_by(@user)

其他解决方案也可以,但会生成一个 sql 查询,当您拥有大量数据时会更快。

【讨论】:

  • 是的,会有很多帖子。所以我会尝试一下,因为我希望它轻巧快速
  • 很好,如果它有效,请告诉我,但仍有可能我没有犯错;)
【解决方案3】:

似乎@user.likes@ 没有返回与Post 相关的数组或ActiveRelation。

如果假设Like 对象具有post_id 属性,那么您可能需要这样修改代码:

@posts = @user.posts.all + @user.likes.map(&amp;:post)

【讨论】:

  • 我认为这是使用 post.inspect 方法后的问题,但现在使用您的方法(仍在使用 post.inspect .inspect 进行检查)
  • 你的Like类是什么样的?
  • 很可能是@user.likes.map(&:post)(不是'posts')
  • 我现在明白了。这非常有效。想知道我是否仍然需要在我的用户模型中使用“has_many :liked_posts, :through => :likes, :source => :post”。现在可以使用它,但希望将来当我开始对其进行更多实施时,我不会遇到任何问题。谢谢你们两个
  • 我发布了另一种我有时也会使用的方法。一般来说 - 我会尽量减少您执行的查询数量,同时保持代码的可读性足以维护和理解。
【解决方案4】:

这是您可以采用的另一种方法,一种将其放入一个查询并可能进行排序的方法。如果您想将所有内容都包含在一个列表中。

class Post < ActiveRecord::Base

  def self.visible_to(user)
    where('posts.user_id = :user_id or likes.user_id = :user_id', { :user_id => user.id}).includes(:likes).order('created_at desc')
  end

end

然后在控制器中,你会这样做

@posts = Post.visible_to(@user)

【讨论】:

  • 这看起来更干净、更轻巧,但不是它给我这个错误“参数数量错误(1 比 0)”
  • 我删除了“sort('created_at desc')”,现在它可以工作了。谢谢你。一个快速的问题 - 是否可以按照喜欢的方式而不是创建时间来对喜欢进行排序? (例如,帖子是 5 天前创建的,我喜欢,现在它在我今天早些时候创建的帖子之前显示在我今天的页面上)
  • 对不起,应该是“订单”。 'sort' 是一个数组方法,order 是针对活动记录的。按孩子排序有点棘手,存在潜在的唯一性问题,但您可以尝试 order('likes.created_at')。您也可以尝试使用 has_many through 方法进行订购。做一个额外的关联。 has_many :sorted_likes :class_name => 'Like', :order => 'likes.created_at'。然后做 has_many :sorted_liked_posts :through => :sorted_likes, :source => :post。
  • order('likes.created_at') 不起作用,但我将尝试第二个,并尝试并回复显示解决方案(如果我解决了)。再次感谢@Swards
  • 尝试了第二种方法但无济于事.. Stick 无法整理:(.. 帖子整理得很好,但是当我喜欢一个帖子时,它会显示在用户的页面上是创建的(在他所有已经发布的帖子之后),而不是在“喜欢”的时候(在他已经发布的帖子之前)。我仍然会解决这个问题,但如果有人可以借手,那会很有帮助
猜你喜欢
  • 2017-06-15
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 2017-10-14
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
相关资源
最近更新 更多