create object from class name as string in ruby - ruby

I have a model source (name, url, method)
The program parses the source's url for data. Now I have differen classes for parsing different types of urls: rss, xml, ogdata ...
So I have a common interface
new(url) //Parses the url
getTitle() //Get the title of the data
getPrice() //Get the price
And I have four classes rss, xml, ogdata. These classes are in seperate files. The idea is to add more classes as I discover different types of pages. I want to initiate the right classes for the url.
method=source.method
//NOw I want to create a new class of the name specified in method
parser=Rss.new(source.url)//Instead of this
//Something like
parser=.new(source.url)

You can try using const_get.
Ex:-
Kernel.const_get("YourClassNameHere").new
*Kernel.const_get("YourClassNameHere")* will get you the class. And you can use it to instantiate new instances of the class.

irb(main):081:0> User.name
=> "User"
then
"User".constantize.new(name: 'David')
or
User.name..constantize.new(name: 'David')

Related

Passing json "data" array in Retrofit 2

I'm trying retrofit 2 for the first time and I have no idea how to tell it to get "Category" objects from an jsonarray named "data".
Method 1
If I do it like this it fails:
#GET("category")
Call<List<Category>> listCategories();
Method 2
But when I make a new model, called "Categories", which holds a List and is annotated with #SerializedName("data"), it works flawlessly.
#GET("category")
Call<Categories> listCategories();
My Question
Should I annotate something in the interface, like this
#GET("category")
#Annotation to look inside "data"
Call<List<Category>> listCategories();
Or should I annotate my "Category" model to tell Retrofit (or GSON)
that it lives inside the json array "data"?
JSON
{"data":[{"id":1,"name":"Fist Name","parent":0},{"id":2,"name":"Second Name","parent":1}]}
Method 2 Is correct and we use it when we dont want to use/define the json response object/arrays key names(field names). instead provide our own. Eg. In below code List object name is items but while Serialization and Deserialization it uses, what you have defined in #SerializedName annotation that is data.
public class Categories {
//solution 1
List<Category> data;//object name must match with the json response
//solution 2
#SerializedName("data")
List<Category> items;
}
Should I annotate something in the interface
No. There is no such annotation available and everything you can do is only in Response type class.

Spring Data Rest Mongo - how to create a DBRef using an id instead of a URI?

I have the following entity, that references another entity.
class Foo {
String id;
String name supplierName;
**#DBRef** TemplateSchema templateSchema;
...
}
I want to be able to use the following JSON (or similar) to create a new entity.
{
"supplierName": "Stormkind",
"templateSchema": "572878138b749120341e6cbf"
}
...but it looks like Spring forces you to use a URI like this:
{
"supplierName": "Stormkind",
"templateSchema": "/template-schema/572878138b749120341e6cbf"
}
Is there a way to create the DBRef by posting an ID instead of a URI?
Thanks!
In REST, the only form of ID's that exist are URIs (hence the name Unique Resource Identifier). Something like 572878138b749120341e6cbf does not identify a resource, /template-schema/572878138b749120341e6cbf does.
On the HTTP level, entities do not exist, only resources identified by URIs. That's why Spring Data REST expects you to use URIs as identifiers.

How to change the display name for LabelFor in razor in mvc3?

In razor engine I have used LabelFor helper method to display the name
But the display name is seems to be not good to display.
so i need to change my display name how to do it....
#Html.LabelFor(model => model.SomekingStatus, new { #class = "control-label"})
You could decorate your view model property with the [DisplayName] attribute and specify the text to be used:
[DisplayName("foo bar")]
public string SomekingStatus { get; set; }
Or use another overload of the LabelFor helper which allows you to specify the text:
#Html.LabelFor(model => model.SomekingStatus, "foo bar")
And, no, you cannot specify a class name in MVC3 as you tried to do, as the LabelFor helper doesn't support that. However, this would work in MVC4 or 5.
This was an old question, but existing answers ignore the serious issue of throwing away any custom attributes when you regenerate the model. I am adding a more detailed answer to cover the current options available.
You have 3 options:
Add a [DisplayName("Name goes here")] attribute to the data model class. The downside is that this is thrown away whenever you regenerate the data models.
Add a string parameter to your Html.LabelFor. e.g. #Html.LabelFor(model => model.SomekingStatus, "My New Label", new { #class = "control-label"}) Reference: https://msdn.microsoft.com/en-us/library/system.web.mvc.html.labelextensions.labelfor(v=vs.118).aspx The downside to this is that you must repeat the label in every view.
Third option. Use a meta-data class attached to the data class (details follow).
Option 3 - Add a Meta-Data Class:
Microsoft allows for decorating properties on an Entity Framework class, without modifying the existing class! This by having meta-data classes that attach to your database classes (effectively a sideways extension of your EF class). This allow attributes to be added to the associated class and not to the class itself so the changes are not lost when you regenerate the data models.
For example, if your data class is MyModel with a SomekingStatus property, you could do it like this:
First declare a partial class of the same name (and using the same namespace), which allows you to add a class attribute without being overridden:
[MetadataType(typeof(MyModelMetaData))]
public partial class MyModel
{
}
All generated data model classes are partial classes, which allow you to add extra properties and methods by simply creating more classes of the same name (this is very handy and I often use it e.g. to provide formatted string versions of other field types in the model).
Step 2: add a metatadata class referenced by your new partial class:
public class MyModelMetaData
{
// Apply DisplayNameAttribute (or any other attributes)
[DisplayName("My New Label")]
public string SomekingStatus;
}
Reference: https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.metadatatypeattribute(v=vs.110).aspx
Notes:
From memory, if you start using a metadata class, it may ignore existing attributes on the actual class ([required] etc) so you may need to duplicate those in the Meta-data class.
This does not operate by magic and will not just work with any classes. The code that looks for UI decoration attributes is designed to look for a meta-data class first.
You can change the labels' text by adorning the property with the DisplayName attribute.
[DisplayName("Someking Status")]
public string SomekingStatus { get; set; }
Or, you could write the raw HTML explicitly:
<label for="SomekingStatus" class="control-label">Someking Status</label>
Decorate the model property with the DisplayName attribute.
#Html.LabelFor(model => model.SomekingStatus, "foo bar")

In Spring MVC 3, how do I bind an object to a query string when the query string parameters don't match up with the object fields?

A 3rd party is sending me part of the data to fill in my domain object via a query string. I need to partially fill in my domain object, and then have the user fill in the rest via a form. I don't have any control over the query string parameters coming in, so I can't change those, but I'd really like to be able to use Spring MVC's data binding abilities, rather than doing it by hand.
How can I do this?
To add some complication to this, some of the parameters will require extensive processing because they map to other objects (such as mapping to a user from just a name) that may not even exist yet and will need to be created. This aspect, I assume, can be handled using property editors. If I run into trouble with this, I will ask another question.
Once I have a partially filled domain object, passing it on to the edit view, etc. is no problem, but I don't know how to properly deal with the initial domain object population.
The only thing I have been able to come up with so far is to have an extra class that has it's properties named to match the inbound query parameters and a function to convert from this intermediary class to my domain class.
This seems like a lot of overhead though just to map between variable names.
Can you not just have the getter named differently from the setter, or have 2 getters and 2 setters if necessary?
private int spn;
// Standard getter/setter
public int getSpn() {
return spn;
}
public void setSpn(int spn) {
this.spn = spn;
}
// More descriptively named getter/setter
public int getShortParameterName() {
return spn;
}
public void setShortParameterName(int spn) {
this.spn = spn;
}
Maybe that is not standard bean convention, but surely would work?

Handle GUIDs in ASP.Net MVC 3

I have a bunch of tables in my database that have a column which is of type GUID. I do not want this to be a part of scaffolding when i generate my views, so i am using [ScaffoldColumn(false)]. I don't want the user to enter an actual GUID when "creating" a new entity. Is there any way to automate the process of automatically adding a new GUID (thru data annotations or some other way??) when a user creates a new Entity or do i have to modify the controller for every table that has a GUID so that every time a user creates a new entry i make sure i generate a new GUID before saving it?
Thanks.
This is where (IMHO) the new scaffolding features encourages bad code.
You should define separate ViewModels for your views. These contain only the fields you wish the user to change along with any view specific validation/rules.
Within your controller action, you can check whether the user input is valid (ModelState.IsValid) and if so, do some lefty-righty mapping between your ViewModel properties and those of your entity.
See ViewModel Best Practices for more details.
However, to answer your question, you can use the HiddenInput attribute on an Id field so that it is rendered as a <input type="hidden"...
With regard with setting the Id, create a base class for your entities e.g:
public abstract class BaseEntity {
public Guid Id {get;set;}
public BaseEntity() {
Id = Guid.NewGuid();
}
}
You can then inherit your entities from this class and when you call new MyEntity() the base class constructor will be invoked, thus setting the Id.

Resources