我正在开发我的第一个应用程序,而Devise给了我一些问题。我在一个模型上设计了一个与其他3个模型Artist,Label,Fan有多态关联的用户。一切都是正确的,但是当我创建一个新的艺术家时,一切正常。当我与该艺术家重新签名时,例如,如果User_id为2且Artist_id为4,我将在Artists控制器中的Show Action上找到“找不到'id'= 2的艺术家”。我已经编辑了after_sign_in_path_for方法来检测帐户类型,以便在登录后重定向到用户类型的正确路径,从日志看起来艺术家的show动作试图匹配User_id而不匹配记录的Artist_id在用户中。
我的模特:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
belongs_to :account, polymorphic: true
validates_uniqueness_of :user_name
end
class Artist < ActiveRecord::Base
has_one :user, as: :account, dependent: :destroy
has_many :tracks, dependent: :destroy
accepts_nested_attributes_for :user
validates_uniqueness_of :artist_name
has_attached_file :avatar,
:styles => { :medium => "300x300>", :thumb => "64x64>" },
:default_url => "https://s3-us-west- 2.amazonaws.com/trackfilter/default/default_250.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
class Fan < ActiveRecord::Base
has_one :user, as: :account, dependent: :destroy
accepts_nested_attributes_for :user
has_attached_file :avatar,
:styles => { :medium => "300x300>", :thumb => "150x150>" },
:default_url => "https://s3-us-west-2.amazonaws.com/trackfilter/default/default_250.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
class Label < ActiveRecord::Base
has_one :user, as: :account, dependent: :destroy
accepts_nested_attributes_for :user
validates_uniqueness_of :label_name
has_attached_file :avatar,
:styles => { :medium => "300x300>", :thumb => "150x150>" },
:default_url => "https://s3-us-west-2.amazonaws.com/trackfilter/default/default_250.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
应用程序控制器:
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
if current_user.account_type == "Artist"
artist_path(resource)
elsif current_user.account_type == "Label"
label_path(resource)
else current_user.account_type == "Fan"
fan_path(resource)
end
end
end
艺术家控制器:
class ArtistsController < ApplicationController
before_action :authenticate_user!, :except => [:index, :show]
before_action :set_artist, only: [:show, :edit, :update, :destroy]
def show
@artist = Artist.find(params[:id])
@tracks = @artist.tracks.all
end
日志:
Started POST "/users/sign_in" for 127.0.0.1 at 2014-07-10 16:19:23 -0600
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"bdHPGqkUlW2OkJiP0qHaJOI1fnEMR3o+wZEwrWoQVxs=", "user"=> {"email"=>"dino@dino.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'dino@dino.com' ORDER BY "users"."id" ASC LIMIT 1 (0.1ms) begin transaction SQL (0.3ms) UPDATE "users" SET "current_sign_in_at" = ?, "last_sign_in_at" = ?, "sign_in_count" = ?, "updated_at" = ? WHERE "users"."id" = 2 [["current_sign_in_at", "2014-07-10 22:19:23.660435"], ["last_sign_in_at", "2014-07-10 22:15:59.573569"], ["sign_in_count", 26], ["updated_at", "2014-07-10 22:19:23.661056"]](4.0ms) commit transaction
Redirected to http://localhost:3000/artists/2
Completed 302 Found in 78ms (ActiveRecord: 4.6ms)
Started GET "/artists/2" for 127.0.0.1 at 2014-07-10 16:19:23 -0600
Processing by ArtistsController#show as HTML
Parameters: {"id"=>"2"}
Artist Load (0.1ms) SELECT "artists".* FROM "artists" WHERE "artists"."id" = ? LIMIT 1 [["id", 2]]
Completed 404 Not Found in 1ms
ActiveRecord::RecordNotFound - Couldn't find Artist with 'id'=2:
对我来说很清楚,它是通过Devise用户ID而不是艺术家ID ...有关如何解决此问题的任何想法?
...谢谢
答案 0 :(得分:0)
您的问题在重定向中,您需要提供帐户,因为它是您的artist / fan_controller查找对象所需的帐户ID。
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
if resource.account_type == "Artist"
artist_path(resource.account)
elsif resource.account_type == "Label"
label_path(resource.account)
else resource.account_type == "Fan"
fan_path(resource.account)
end
end
end
或更好(相同的逻辑,不同的写作):
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
account = resource.account
case account
when 'Artist' then artist_path(account)
when 'Label' then label_path(account)
when 'Fan' then fan_path(account)
else
#Handle error
end
end
end
甚至更时髦/灵活/危险:
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
self.public_send("#{resource.account_type.to_s.downcase.underscore}_path".to_sym, resource.account)
end
end