Добавить условие проверки только для пользователя logged_in -
<% if current_user.present? %>
<script>
//analytics stuffs
ga('create', 'UA-1234567-1', 'auto', { 'userId': <%= current_user.id %> }); // Set the user ID using signed-in user_id.
ga('send', 'pageview');
</script>
<% end %>
Или
<script>
//analytics stuffs
ga('create', 'UA-1234567-1', 'auto', { 'userId': <%= current_user.present? ? current_user.id : nil %> }); // Set the user ID using signed-in user_id.
ga('send', 'pageview');
</script>
Я думаю, что использование политики Fast
или Slow
может помочь установить правильное колесо для данного типа автомобиля (где оба Car
и Wheel
зависят от политики, а объект Car
имеет, скажем, частную совокупность колес).
Это решение не является полиморфным, но может быть вашим единственным вариантом, если вам нужна видимость на уровне базового класса:
abstract class Car
{
private CarWheel wheel;
public CarWheel Wheel
{
get { return wheel; }
protected set { wheel = value; }
}
}
class FastCar : Car
{
public new FastCarWheel Wheel
{
get { return base.Wheel as FastCarWheel; }
set { base.Wheel = value; }
}
}
class SlowCar : Car
{
public new SlowCarWheel Wheel
{
get { return base.Wheel as SlowCarWheel ; }
set { base.Wheel = value; }
}
}
Возможно, вы захотите оценить, выполняет ли ваш базовый класс слишком много. Возможно, можно решить вашу проблему, разделив ваши классы на множество небольших классов. С другой стороны, иногда это неизбежно.
Поскольку ваша цель состоит в том, чтобы позволить клиентскому коду вернуть свойство обратно как WheelPart, но только установите его в качестве определенного подкласса, у вас есть несколько вариантов. Хотя я боюсь, что ни один из них не очень чистый.
Во-первых, вы можете выдать ошибку времени выполнения, если задан неправильный тип:
public abstract class Car
{
public abstract WheelPart Wheel { get; set; }
}
public class FastCar : Car
{
private FastWheel _wheel;
public override WheelPart Wheel
{
get { return _wheel; }
set
{
if (!(value is FastWheel))
{
throw new ArgumentException("Supplied wheel must be Fast");
}
_wheel = (FastWheel)value;
}
}
}
Но я бы не стал этого делать, так как для клиентского кода очень непонятно, что любой другой тип колеса выдаст исключение, и они не получат никакой обратной связи от компилятора.
Я бы создал ICar и затем определил ваши автомобили таким образом, вместо абстрактного класса
interface ICar
{
IWheel Wheel {get; set;}
}
class FastCar: ICar
{
FastWheel fastWheel;
IWheel Wheel
{
get { return fastWheel; }
set
{
if (value is FastWheel) fastWheel = (FastWheel)value;
}
}
}
class SlowCar: ICar
{
SlowWheel slowWheel;
IWheel Wheel
{
get { return slowWheel; }
set
{
if (value is SlowWheel ) slowWheel = (SlowWheel )value;
}
}
}
class FastWheel: IWheel {}
class SlowWheel: IWheel {}
Определите интерфейс колеса (IWheel):
public interface IWheel
{
}
Реализуйте интерфейс для FastCarWheel и SlowCarWheel, например
public class FastCarWheel : IWheel
{
}
Теперь ваш абстрактный класс становится следующим:
abstract class Car
{
public IWheel Wheel { get; set; }
}
Подклассы Car могут свободно использовать любую реализацию Wheel, которую они выбирают:
FastCar fastCar = new FastCar();
fastCar.Wheel = new FastCarWheel();