【发布时间】:2014-05-15 19:10:26
【问题描述】:
我一直在使用 Rails 4 开发一个 Web 应用程序,并使用 Michael Hartl 教程作为它的主干,但也使用了 Devise。在构建了一些之后,我返回并将 Status 模型更改为多态模型,以允许用户、场所和组能够发布状态。到目前为止,我已经有了一定的方法,但现在卡住了。尝试查看用户的个人资料时,我目前收到此错误:
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>
用户肯定有一个头像,据我所知,它似乎无法通过多项式关系来计算关联。它在 user#show 页面上,所以大概我不应该将“user”更改为“statusable”,无论如何我已经尝试过了,但不明白问题出在哪里。该配置文件显示当前状态的提要以及每个用户的头像。
任何帮助将不胜感激。
编辑
这是我的用户和状态模型:
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
【问题讨论】:
-
你能发布你的模型吗?
标签: ruby-on-rails polymorphism polymorphic-associations