Setting instance variable to parent in inherited resources - instance-variables

I'm trying out IR and im having some issues setting an instance variable to a nested parent object. For example, I have a professional model that has many projects. In my projects controller, I have this:
class ProjectsController < InheritedResources::Base
belongs_to :professional, :optional => true
And for all the actions I want to set a #professional instance variable for the parent project.
I tried a before filter, like this:
class ProjectsController < InheritedResources::Base
belongs_to :professional, :optional => true
before_filter :set_professional
private
def set_professional
#professional = #project.professional
end
But I believe it's being called before IR has a chance to set the #project instance variable.
How can I do this?

Related

Inheriting from Sealed classes in MATLAB

In MATLAB, one of the attributes of a class (defined after classdef) is Sealed, which means that no class can use it as a superclass (or to be more precise, "to indicate that these classes have not been designed to support subclasses."1).
For example, if I try to instantiate a class that's defined as below (considering table is Sealed):
classdef SomeLie < table
end
I would get the 'MATLAB:class:sealed' error:
>> A = SomeLie;
Error using SomeLie
Class 'table' is Sealed and may not be used as a superclass.
As I refuse to be told by a machine what I may or may not do, I would like to subclass a Sealed class, regardless. How can I do that in MATLAB R2017a?
I'm having a hard time believing that this system is completely airtight, so I'm looking for a solution that would cause the Sealed attribute to be silently ignored (or something of that sort). The desired solution should work without modifying any "library class definitions" to remove Sealed from them.
I tried playing around with "reflection", but arrived at a dead end...
classdef SomeLie % < table
properties (Access = private)
innerTable table;
end
properties (GetAccess = public)
methodHandles struct = struct();
end
methods
function slObj = SomeLie(varargin)
slObj.innerTable = table(varargin{:});
% methodHandles = methods(slObj.innerTable);
ml = ?table; ml = {ml.MethodList.Name}.';
ml = setdiff(ml,'end');
tmpStruct = struct;
for indM = 1:numel(ml)
tmpStruct.(ml{indM}) = str2func([...
'#(varargin)' ml{indM} '(slObj.innerTable,varargin{:})']);
end
slObj.methodHandles = tmpStruct;
end
function varargout = subsref(slObj,varargin)
S = struct(slObj);
varargout{:} = S.methodHandles.(varargin{1}.subs)(varargin{:});
end
end
end
(There's no need to fix the above code, I was just sharing)
I do not think the machine is the problem, but the class designer and he certainly has good motivations to seal the class. "Philosophy" of coding, a part, you could 'own' the class in a wrapper class without defining it sealed.
For example, supposer the class Hello is sealed and has a method (or function, if you wish) sayHello which you would like to use in inherited classes you could define a class FreeHello (public) which contains an instance of Hello. At the constructor you build the corresponding Hello and then you define a sayHello method whose body simply calls your Hello instance and makes it execute the sayHello method (and returns the output, accordingly).
In order to 'open' the sealed class, you need to do these for all properties and public methods; of course you are still not capable of accessing private methods, but now you can subclass your wrapper class, as you wish.

Why does VB disallow type conversion from parent to subclass?

I have already asked a question here where I basically require an instance of a base class to be converted into a subclass (or a new instance of the subclass to be created using the instance of the base class' properties). The conclusion seems to be that the best way to do this is to manually assign every property I need to transfer in the constructor of the base class.
While this is feasible in some cases, it certainly is not when there are many properties to transfer, or when the base class is subject to change — every time you add a property to the base class, the constructor needs to be changed too, so this solutions is inelegant.
I have searched online, and can't see any reason for why this kind of type-casting isn't implemented. The arguments I have seen so far describe this operation to 'not make any sense' (making a minivan from a car was an analogy I saw), question what to do about the non-inherited variables in the subclass, or claim that there must be some better solution for what was trying to be achieved.
As far as I can see, the operation doesn't need to 'make sense' as long as it's useful, so that isn't much of a good reason. What's wrong with adding a few more properties (and perhaps methods/overriding them) to change an instance into a subclass? In the case of the non-inherited variables, that can simply be solved by allowing this kind of type-cast only a constructor is added to the subclass or by just simply setting them to their default values. After all, constructors usually call MyBase.New(...) anyway. What's the difference between using the constructor of the base (essentially creating a new instance of the base) and using an instance which is already initialised? Lastly, I don't think the third argument is well-justified — there are times when all of the other solutions are inelegant.
So finally, is there any other reason for why this kind of casting isn't allowed, and is there an elegant way to circumvent this?
Edit:
Since I don't know a lot about this topic, I think I meant to say 'convert' rather than 'cast'. I'll also add an example to show what I'm trying to succeed. The conversion would only be allowed at the initialisation of the Subclass:
Class BaseClass
Dim x as Integer
Dim y as Integer
End Class
Class Subclass1 : Inherits BaseClass
Dim z as Integer
Sub New(Byval value As Integer)
'Standard initialisation method
MyBase.New()
z = value
End Sub
Sub New(Byval value As Integer, Byval baseInstance As BaseClass)
'Type conversion from base class to subclass
baseInstance.passAllproperties()
'This assigns all properties of baseInstance belonging to BaseClass to Me.
'Properties not in BaseClass (eg. if baseInstance is Subclass2) are ignored.
z = value
End Sub
End Class
Class Subclass2 : Inherits BaseClass
Dim v As Integer
End Class
What you describe is not casting. Have you ever heard the expression"to cast something in a different light"? It means to look at the same thing in a different way or to make the same thing look different. That is the exact way that the term "cast" is used in programming. When you cast, you do NOT change the type of the object but only the type of the reference used to access the object. If you want to cast from a base type to a derived type then the object you're referring to has to actually be that derived type. If it's not then you're not performing a cast but rather a conversion.
So, why can't you convert an instance of a base type to an instance of a derived type. Well, why would you be able to? Yes, it's something that might save writing a bit of code on occasion but does it actually make sense? Let's say that you have a base type with one property and a derived type that adds another property. Let's also say that that derived type has constructors that require you to provide a value for that second property. You're suggesting that the language should provide you with a way to magically convert an instance of the base class into an instance of the derived class, which would mean it would have to slow you to circumvent that rule defined by the author via the constructors. Why would that be a good thing?
Use System.Reflection to iterate over properties and fields of the base class and apply them to the derived class. This example includes a single public property and single public field, but will also work with multiple private/protected properties and fields. You can paste the entire example into a new console application to test it.
Imports System.Reflection
Module Module1
Sub Main()
Dim p As New Parent
p.Property1 = "abc"
p.Field1 = "def"
Dim c = New Child(p)
Console.WriteLine("Property1 = ""{0}"", Field1 = ""{1}""", c.Property1, c.Field1)
Console.ReadLine()
End Sub
Class Parent
Public Property Property1 As String = "not set"
Public Property Field1 As String = "not set"
End Class
Class Child
Inherits Parent
Public Sub New(myParent As Parent)
Dim fieldInfo = GetType(Parent).GetFields(BindingFlags.NonPublic _
Or BindingFlags.Instance)
For Each field In fieldInfo
field.SetValue(Me, field.GetValue(myParent))
Next
Dim propertyInfo = GetType(Parent).GetProperties(BindingFlags.NonPublic _
Or BindingFlags.Instance)
For Each prop In propertyInfo
prop.SetValue(Me, prop.GetValue(myParent))
Next
End Sub
End Class
End Module
Output:
Property1 = "abc", Field1 = "def"
This solution is automated, so you won't need to change anything when adding or removing properties and fields in the base class.
In general, because of this:
Class TheBase
End Class
Class Derived1 : TheBase
Sub Foo()
End Sub
End Class
Class Derived2 : TheBase
Sub Bar()
End Sub
End Class
Sub Main()
Dim myDerived1 As New Derived1
' cast derived to base
Dim myTheBase = CType(myDerived1, TheBase)
' cast base to derived?
' but myTheBase is actually a Derived1
Dim myDerived2 As Derived2 = CType(myTheBase, Derived2)
' which function call would you like to succeed?
myDerived2.Foo()
myDerived2.Bar()
End Sub

Rails 4: form object for update action for 2 models

I have a form object that handles 2 associated objects. I'm trying to get some validation working on the form object, but am not having much success.
I think the issue is that the attributes I'm validating are delegated to the model objects, but I'm not sure how else to handle this situation: when the form is displayed, these attributes need to pull from the actual models to show the values on the form in edit mode, but when I update the form, I need to validate the submitted parameters, not the values being pulled from the models themselves.
One thought I have is using a EditBorrowerForm object that pulls attributes from associated models and a UpdateBorrowerForm that performs all the validations and updates the models. But that seems like a lot of extra work for something trivial.
I've seen a lot of form objects used for CREATE actions (where you only validate fields before passing them to the models), but haven't seen any good examples of UPDATE actions (where you need to both pull fields from models as well as update them).
Here are the models I'm working with:
class Client < ActiveRecord::Base
has_many :borrowers
end
class Borrower < ActiveRecord::Base
belongs_to :client
end
And my form object:
class BorrowerForm
include ActiveModel::Model
attr_accessor :client, :borrower
delegate :first_name, :last_name, :date_of_birth, to: :client
delegate :citizenship, :marital_status, to: :borrower
validates :first_name, :last_name, :citizenship, presence: true
def initialize(borrower)
#borrower = borrower
#client = #borrower.client
end
def update_attributes(params)
# Never validates properly...
if valid?
ActiveRecord::Base.transaction do
borrower.update_attributes(params.slice(:citizenship, :marital_status)
client.update_attributes(params.slice(:first_name, :last_name, :date_of_birth)
end
true
else
false
end
end
end
And the controller:
class BorrowersController < ApplicationController
def edit
#borrower = BorrowerForm.new(Borrower.find(params[:id])
end
def update
#borrower = BorrowerForm.new(Borrower.find(params[:id])
if #borrower.update_attributes(params)
redirect_to :index
else
render :edit
end
end
end

Rails 4: deciding which inherited child class to use in parent class initializer

I have a Report class that several models inherit from (OverviewReport, CategoryReport, etc...). Each of these inherited classes has specific methods/attributes that need to be customized for that type of report.
The desired report type is passed in via the params hash, so I can do something like the following:
# reports_controller.rb
def index
case params[:type]
when "overview" then OverviewReport.new(...)
when "category" then CategoryReport.new(...)
...etc...
end
end
This works, but I would like to clean up the controller a little bit. I would like to be able to do this:
# reports_controller.rb
def index
#report = Report.new(params[:type], ...)
end
# report.rb class
def initialize(type, options)
case type
when "overview" then self = OverviewReport.new(type, options)
when "category" then self = CategoryReport.new(type, options)
end
end
However, you can't change the value of self, so how would you go about accomplishing this functionality?
The intent is the clean up the controller code and abstract away which report you're using, so I can call #report.some_method() and it will call the inherited-specific method.
Is there a clean solution to this, or am I stuck with a (somewhat) lengthy case statement in my controller?
One solution would be to use a "factory" class whose sole purpose is to instantiate the correct class:
# reports_controller.rb
def index
#report = AgnosticReport.new(type)
end
# agnostic_report.rb
def initialize(type)
case type
when "overview" then return OverviewReport.new(type)
when "category" then return CategoryReport.new(type)
...etc...
end
end
This is perfectly acceptable, but I was wondering if there was any need to add a "third" layer of classes to this situation.
Do you have the ability to change the type params passed?
If so I would use constantize
params[:type] being "Overview Report" or "Category Report" e.t.c.
then use
#report = params[:type].constantize.new
s = "OverviewReport",
s.constantize => OverviewReport

How to Use ActiveResource with Shallow Nested Routes?

I have a Rails application that has a Company resource with a nested resource Employee. I'm using shallow routing, so to manipulate Employee, my routes are:
GET /employees/1
PUT /employees/1
DELETE /employees/1
POST /companies/1/employees
How can I create, read, update, and destroy Employees using ActiveResource?
To create employees, I can use:
class Employee < ActiveResource::Base
self.site = "http://example.com/companies/:company_id"
end
But if I try to do:
e=Employee.find(1, :params => {:company_id => 1})
I get a 404 because the route /companies/:company_id/employees/:id is not defined when shallow routes are used.
To read, edit, and delete employees, I can use:
class Employee < ActiveResource::Base
self.site = "http://example.com"
end
But then there doesn't seem to be a way to create new Employees, due to the lack of the companies outer route.
One solution would be to define separate CompanyEmployee and Employee classes, but this seems overly complex.
How can I use a single Employee class in ActiveResource to perform all four CRUD operations?
I'm using Rails 3.0.9. You can set the prefix like this:
class Employee < ActiveResource::Base
self.prefix = "/companies/:company_id/"
end
And then
Employee.find(:all, :params => {:company_id => 99})
or
e = Employee.new(:name => "Corey")
e.prefix_options[:company_id] = 1
It will replace :company_id with the value from prefix_options.
There is a protected instance method named collection_path that you could override.
class Employee < ActiveResource::Base
self.site = "http://example.com"
def collection_path(options = nil)
"/companies/#{prefix_options[:company_id]}/#{self.class.collection_name}"
end
end
You would then be able to this to create employees.
e = Employee.new(:name => "Corey")
e.prefix_options[:company_id] = 1
e.save
It doesn't seem like the prefix_options is documented other than in the clone method so this might change in future releases.
See this article: http://blog.flame.org/2009/11/04/activeresource-and-shallow-nested-routes.html
Here, the author proposes to override class method collection_path. This makes sense, since this method is used also by new_element_path and will retrieve the same path in both cases.
Example:
class Employee < ActiveResource::Base
self.site = "http://example.com"
def self.collection_path(prefix_options = {},query_options=nil)
super
"/companies/#{query_options[:company_id]}/#{collection_name}.#{format.extension}#{query_string(query_options)}"
end
end
Then you can find employees for a company by doing:
company = Company.find(:first)
Employee.find(:all, :params => {:company_id => company.id })
I found it best to override ActiveResource::Base.element_path with the same functionality as defined in the library, but omitting the use of prefix_options in the returned value. There is no
class Employee < ActiveResource::Base
self.site = 'http://example.com'
self.prefix = '/companies/:company_id/'
# Over-ride method and omit `#{prefix(prefix_options)}` from the returned string
def self.element_path(id, prefix_options = {}, query_options = nil)
"/#{collection_name}/#{URI.parser.escape id.to_s}.#{format.extension}"
end
end
The Employee class will then behave as usual, with no need to assign prefix_options to the instance as suggested in other solutions.