Как да поръчам контролер по виртуален атрибут, който приема параметър?

Опитвам се да поръчам индекс „Публикуване“ до последната дата на активност от current_user или приятелите на current_user. Публикацията може да бъде създадена или повторно публикувана (различен модел).

Използвайки настоящия си подход, получавам "недефиниран метод `last_friend_update' за #Class:0x000000023a0e38"

Модели
Модел на публикация:

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :reposts
  has_many :resposters, :through => :resposts, :source => :user

  def self.from_users_followed_by(user)
    followed_user_ids = user.friend_ids
    repost_ids = user.reposts.map(&:post_id)
    friend_reposts_ids = user.friend_reposts.map(&:post_id)
    comment_ids = user.comments.map(&:post_id)
    friend_comment_ids = user.friend_comments.map(&:post_id)
    where(['user_id IN (:followed_user_ids) OR user_id = :user_id 
            OR id IN (:repost_ids) OR id IN (:friend_reposts_ids)
            OR id IN (:comment_ids) OR id IN (:friend_comment_ids)',
      {followed_user_ids: followed_user_ids, user_id: user, 
       repost_ids: repost_ids, friend_reposts_ids: friend_reposts_ids,
       comment_ids: comment_ids, friend_comment_ids: friend_comment_ids}])
  end

def self.last_friend_update(user)
    post_date = :created_at.to_s
    user_repost_date = user.reposts.where(['post_id = :post_id',{post_id: :id}]).map(&:created_at).max.to_s
    friends_repost_date = user.friend_reposts.where(['post_id = :post_id',{post_id: :id}]).map(&:created_at).max.to_s
    user_comment_date = user.comments.where(['post_id = :post_id',{post_id: :id}]).map(&:created_at).max.to_s
    friend_comment_date = user.friend_comments.where(['post_id = :post_id',{post_id: :id}]).map(&:created_at).max.to_s
    most_recent_date = [post_date, user_repost_date, user_comment_date, friend_comment_date].max.to_s
  end

Потребителски модел

class User < ActiveRecord::Base
  has_many :posts
  has_many :friendships, dependent: :destroy
  has_many :friends, :through => :friendships
  has_many :reposts
  has_many :reposted_posts, :through => :reposts, :source => :post
  has_many :friend_posts, :through => :friendships, :source => :posts
  has_many :friend_reposts, :through => :friendships, :source => :reposts
end

Модел на приятелство:

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => "User"
  has_many :posts, :foreign_key => "user_id", :primary_key => "friend_id"
  has_many :reposts, :foreign_key => "user_id", :primary_key => "friend_id"
  has_many :comments, :foreign_key => "user_id", :primary_key => "friend_id"
end

Контрольор на публикации

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  # GET /posts
  # GET /posts.json
  def index
    if user_signed_in?
      @posts = Post.from_users_followed_by(current_user).sort_by("#{Post.last_friend_update(current_user)}")
    else
      @all_posts = Post.all.order("created_at desc")
    end
  end

  private
  def post_params
    params.require(:post).permit(:user_id, :url, :summary, :title, :last_friend_udpate)
  end
end  

Актуализация

Модел на пост

  def last_friend_update(user)
    # setting some initial variables here, so they won't error if null later
    post_date = self.created_at.to_datetime
    user_repost_date = "01-01-1960".to_datetime
    friends_repost_date = "01-01-1960".to_datetime
    user_comment_date = "01-01-1960".to_datetime
    friend_comment_date = "01-01-1960".to_datetime
    # Getting most recent dates for the current_user and their firends on the post
    user_repost_maxdate = user.reposts.where(['post_id = :post_id',{post_id: self.id}]).map(&:created_at).max
    friends_repost_maxdate = user.friend_reposts.where(['post_id = :post_id',{post_id: self.id}]).map(&:created_at).max
    user_comment_maxdate = user.comments.where(['post_id = :post_id',{post_id: self.id}]).map(&:created_at).max
    friend_comment_maxdate = user.friend_comments.where(['post_id = :post_id',{post_id: self.id}]).map(&:created_at).max
    # If there are recent dates for activities, set the variables as such
    unless user_repost_maxdate.nil?
      user_repost_date = user_repost_maxdate.to_datetime
    end
    unless friends_repost_maxdate.nil?
      friends_repost_date = friends_repost_maxdate.to_datetime
    end
    unless user_comment_maxdate.nil?
      user_comment_date = user_comment_maxdate.to_datetime
    end
    unless friend_comment_maxdate.nil?
      friend_comment_date = friend_comment_maxdate.to_datetime
    end
    # get the max of the activity date_times.
    [post_date.to_datetime, user_repost_date.to_datetime, friends_repost_date, user_comment_date.to_datetime, friend_comment_date.to_datetime].max
  end

Раздел Post Controller:

# sort_by lets me use the block format, while order_by did not.
# I reverse at the end to have the most recent post at the top.
@posts = Post.from_users_followed_by(current_user).sort_by{ |post| post.last_friend_update(current_user) }.reverse

person Shaun    schedule 04.12.2013    source източник


Отговори (1)


В модела имате last_friend_udpate, в параметрите на публикацията имате last_friend_udpate, но в индекса имате last_friend_update

person kddeisz    schedule 04.12.2013
comment
Добро хващане! Но все още получавам същата грешка. Странно нали? - person Shaun; 04.12.2013
comment
Опитвате се да извикате last_friend_update във вашето действие за индексиране, сякаш е метод на клас. Вероятно сте искали да го дефинирате като метод на клас като self.last_friend_update. Или това, или трябва да използвате блоковата форма на sort_by като sort_by { |post| post.last_friend_update(user).to_s} - person kddeisz; 04.12.2013
comment
Добро решение, поправих това и няколко други проблема в модела. Сега получавам грешен брой аргументи (1 за 0) в контролера. - person Shaun; 04.12.2013
comment
Публикувайте актуализиран код и на кой ред получавате грешката? - person kddeisz; 04.12.2013
comment
Няма значение, промених го от sort_by на order и работи! Благодаря за помощта тук! - person Shaun; 04.12.2013
comment
В крайна сметка приключих с блок формата. Последните съответни секции за контролер на публикации и модели са по-горе за всеки, който се интересува. Сигурен съм, че може да се направи по-красиво, но работи :) - person Shaun; 05.12.2013