多态状态关联

时间:2014-05-15 19:10:26

标签: ruby-on-rails polymorphism polymorphic-associations

我在Rails 4中开发了一个Web应用程序,并使用Michael Hartl教程作为它的主干,但也使用了Devise。在构建了一些之后,我回过头来将状态模型更改为多态,以便允许用户,场所和组发布状态。到目前为止,我已经有了一定的方法,但现在我被卡住了。在尝试查看用户的个人资料时,我目前收到此错误:

NoMethodError in Users#show

Showing /home/app_name/app/views/users/show.html.erb where line #6 raised:

undefined method `avatar' for #<ActiveRecord::AssociationRelation::ActiveRecord_AssociationRelation_Status:0xb6859fd8>
Extracted source (around line #6):

<aside class="col-md-4">
  <section>
    <h1>
        <%= image_tag @user.avatar.url(:thumb) %>
    <%= @user.name %>
    </h1>
  </section>

用户肯定有一个头像,并且据我所知,它似乎无法通过多项式关系计算出关联。它位于用户#show页面上,所以大概我不应该改变用户&#34;无论如何,我已经尝试了这个,但不知道问题的来源。该配置文件显示了当前状态的提要以及每个用户的化身。

非常感谢任何帮助。

修改

以下是我的用户和状态模型:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:facebook, :twitter, :google_oauth2]

    before_save { self.username = username.downcase }

    validates :first_name,    presence: true, 
                              length: { maximum: 25 }
    validates :last_name,     presence: true, 
                              length: { maximum: 25 }
    VALID_USERNAME_REGEX = /\A[\w+\-._]+\z/i
    validates :username,      presence: true, 
                              length: { maximum: 20 },
                              format: { with: VALID_USERNAME_REGEX },
                              uniqueness: { case_sensitive: false }
    validates :email,             presence: true
    validates :password,      presence: true
    validates :birthday,      presence: true
    validates :gender,            presence: true
    validates :postcode,          presence: true
    validates_format_of :postcode, :with =>  /\A([A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s?[0-9][ABD-HJLNP-UW-Z]{2}|(GIR\ 0AA)|(SAN\ TA1)|(BFPO\ (C\/O\ )?[0-9]{1,4})|((ASCN|BBND|[BFS]IQQ|PCRN|STHL|TDCU|TKCA)\ 1ZZ))\z/i, :message => "invalid postcode"

    has_attached_file :avatar, :styles => { :medium => "300x300", :thumb => "100x100", :micro => "30x30", :large => "500x500>" }, :default_url => "/images/:style/missing.jpg"
    validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/

    geocoded_by :address
    after_validation :geocode

    self.per_page = 20

    def address
      [town, postcode, country].compact.join(', ')
    end

    def feed
      Status.from_users_favourited_by(self)
    end

    def self.all_except(user)
      where.not(id: user)
    end
  end


    def name
        first_name + " " + last_name
    end

  has_many :statuses, as: :statusable, dependent: :destroy
  accepts_nested_attributes_for :statuses

end

class Status < ActiveRecord::Base
    before_create :set_latlong

    belongs_to :statusable, polymorphic: true

    default_scope -> { order('created_at DESC') }
    validates :content, presence: true, length: { maximum: 140 }
    validates :statusable_id, presence: true
    validates :statusable_type, presence: true

    def set_latlong
        self.latitude = statusable.latitude
        self.longitude = statusable.longitude
    end

    def self.from_users_favourited_by(user)
        favourited_user_ids = "SELECT favourite_id FROM favouriteusers
                                    WHERE favourited_id = :user_id"
        where("statusable_id IN (#{favourited_user_ids}) OR statusable_id = :user_id", user_id: user.id)
    end
end

这是状态控制器:

    class StatusController < ApplicationController
  before_action :authenticate_user!, only: [:create, :destroy]
  before_filter :load_statusable

  def new
    @status = Status.new(status_params)
  end


  def create
    @statusable = load_statusable
    @status = @statusable.statuses.build(status_params)
    if @status.save
        flash[:success] = "Status created!"
        redirect_to root_url
    else
      @feed_items = []
        render 'static_pages/home'
    end
  end

  def destroy
    @status.destroy
    redirect_to root_url
  end

  private

    def status_params
        params.require(:status).permit(:content)
    end

    def load_statusable
      resource, id = request.path.split('/')[1, 2]
      resource_name = resource.singularize.classify
      if resource_name = "user"
        @statusable = current_user
      else 
        @statusable = resource_name.constantize.find(id)
      end
    end
end

最后是状态架构:

create_table "statuses", force: true do |t|
    t.string   "content"
    t.integer  "statusable_id"
    t.string   "statusable_type"
    t.float    "latitude"
    t.float    "longitude"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

我已经取出一些比特以便于阅读,但希望留下所需的比特。

修改

class UsersController < ApplicationController

before_filter :authenticate_user!, only: [:index, :show,:edit,
:update, :destroy, :favourite_users, :favourited_users]

def index

 @users = User.all_except(current_user).paginate(page: params[:page]).order('created_at DESC')

end


def show

   @user = User.find(params[:id])

   @user = @user.statuses.paginate(page: params[:page])

end


def new

 @user = User.new

end


def edit

   @user = User.find(params[:id])

end


def update

   @user = User.find(params[:id])

    if @user.update_attributes(user_params)

     # Handle a successful update.

    else

     render 'edit'

    end

end


def create

 @user = User.create( user_params )

end


def favourite_users

 @title = "Favourites"

 @user = User.find(params[:id])

 @users = @user.favourite_users.paginate(page: params[:page])

 render 'show_favourite'

end


def favourited_users

 @title = "Listed as a Favourite by"

 @user = User.find(params[:id])

 @users = @user.favourited_users.paginate(page: params[:page])

 render 'show_favourite'

end

1 个答案:

答案 0 :(得分:0)

嗯,@user看起来确实不包含User,而是ActiveRecord::AssociationRelation::ActiveRecord_AssociationRelation_Status。难怪它没有avatar方法!检查控制器代码以查看实际设置的@user。如果您无法理解正在发生的事情,请在此处发布控制器。也可能需要User模型和架构。