如何让Devise返回用户的子类

时间:2015-10-13 11:22:34

标签: ruby-on-rails devise warden

我设计了一个用户身份验证。 UPDATE Color_Table SET Color = "Blue" WHERE Color = "Red";分为UPDATE Color_Table SET Color = "Red" WHERE Color = "TempRed";public ObservableDictionary<int, ObservableDictionary<int, GraphPointViewModel>> Data { get; set; } 等子类。这些不是单表继承类,只是从User继承的普通旧ruby对象。

我喜欢设计&#39; current_user帮助器返回User :: AsProfile的实例。

不幸的是,Device在 <chartingToolkit:Chart Grid.RowSpan="2" Name="GrapherChart"> <chartingToolkit:Chart.Axes> <chartingToolkit:LinearAxis Orientation="X" Interval="50" Minimum="{Binding Xmin}" Maximum="{Binding Xmax}" FontSize="10" Title="Phase"/> <chartingToolkit:LinearAxis Orientation="Y" Interval="500" Minimum="{Binding Ymin}" Maximum="{Binding Ymax}" FontSize="10" ShowGridLines="True" Title="Amplitude"/> </chartingToolkit:Chart.Axes> <chartingToolkit:ScatterSeries DependentValuePath="Value.Key" IndependentValuePath="Key" ItemsSource="{Binding Data}"> <chartingToolkit:ScatterSeries.DataPointStyle> <Style TargetType="chartingToolkit:ScatterDataPoint"> <Setter Property="Background" Value="{Binding Value.Value.Colour}"></Setter> </Style> </chartingToolkit:ScatterSeries.DataPointStyle> </chartingToolkit:ScatterSeries> <chartingToolkit:Chart.LegendStyle> <Style TargetType="Control"> <Setter Property="Width" Value="0"/> <Setter Property="Height" Value="0"/> </Style> </chartingToolkit:Chart.LegendStyle> </chartingToolkit:Chart> 中隐藏了大量的元编程,因此很难理解发生了什么。

在控制器中运行public class GraphPointViewModel : Mvvm.ViewModel { private int _count; public int Count { get { return _count; } set { SetPropertyAndNotify(ref _count, value, new []{"Colour"}); } } public Brush Colour { get { return Count >= 5 ? Brushes.Black : Brushes.Gray; } } } 时,是否可以将Devise配置为返回另一个类(User :: AsProfile)?

或者我必须覆盖控制器中的 public class EventGrapherViewModel : DataHandlingViewModel { private double _xmin; public double Xmin { get { return _xmin; } set { SetPropertyAndNotify(ref _xmin, value); } } private double _ymin = -2500; public double Ymin { get { return _ymin; } set { SetPropertyAndNotify(ref _ymin, value); } } private double _zmin; public double Zmin { get { return _zmin; } set { SetPropertyAndNotify(ref _zmin, value); } } private double _xmax = 400; public double Xmax { get { return _xmax; } set { SetPropertyAndNotify(ref _xmax, value); } } private double _ymax = 2500; public double Ymax { get { return _ymax; } set { SetPropertyAndNotify(ref _ymax, value); } } private double _zmax; public double Zmax { get { return _zmax; } set { SetPropertyAndNotify(ref _zmax, value); } } public ObservableDictionary<int, ObservableDictionary<int, GraphPointViewModel>> Data { get; set; } /// <summary> /// The current channel being graphed. /// Note that less than or equal to 0 means no event data is being graphed. /// </summary> private int _currentChannel; public EventGrapherViewModel() { var syncLock = new object(); Data = new ObservableDictionary<int, ObservableDictionary<int, GraphPointViewModel>>(); // EnableCollectionSynchronization allows updating of the UI when the collection is changed from a background thread. BindingOperations.EnableCollectionSynchronization(Data, syncLock); } public void AddDataPoint(int angle, int amplitude) { try { if (!Data.ContainsKey(angle)) { Data.Add(angle, new ObservableDictionary<int, GraphPointViewModel>()); } var matchingAngle = Data[angle]; if (!matchingAngle.ContainsKey(amplitude)) { matchingAngle.Add(amplitude, new GraphPointViewModel()); } var matchingAmplitudeViewModel = matchingAngle.First(ma => ma.Key == amplitude).Value; matchingAmplitudeViewModel.Count++; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } protected override void GrapherSelectionChanged(GrapherSelection grapherSelection) { Data.Clear(); _currentChannel = (int)grapherSelection; } public override void AddDataPoint(Data dataPoint) { if (_currentChannel <= 0) return; var eventData = dataPoint as EventData; if (eventData == null) return; foreach (var eventDataPoint in eventData.EventDataPoints) { AddDataPoint(eventDataPoint.PhaseAngle, eventDataPoint.AmplitudesByChannel[_currentChannel]); } } 才能这样做,如果是这样,我应该如何调用warden进行正确的身份验证?

1 个答案:

答案 0 :(得分:1)

我最终在我的ApplicationController中重新实现了current_user

由于我不需要让一个用户使用多个会话,我可以简化current_user

class ApplicationController < ActionController::Base
  def current_user
    return @current_user if @current_user
    current = warden.authenticate(scope: :user)
    @current_user = current.becomes(User::AsProfile) if current
  end
end

通过使用ActiveRecords becomes,用户将变为User::AsProfile。我宁愿不进行这种转换并直接使用User::AsProfile#find,但这似乎只有在单独使用Warden时才有可能。

作为旁注:这个问题很好地展示了当库实现设计不良的类继承时会发生什么。或者,在这种情况下,根本没有继承。 Devise代码简单地将你的 ApplicationController monkeypatches并在那里添加方法。永远不是一个好主意。事后看来,Devise应该只是一些开发人员可以选择并添加到他的控制器中的模块(关注点)。