Grails Fields Plugin using field templates issue - templates

unfortunatly I can't find any good example where use of the Grails fields plugin is made.
WIthin my app I would like to have some field rendered as a different type like text area or later the CKE editor. My domain:
class Case {
String description
}
I've created a _input.gsp that is found by the plugin:
INFO formfields.FormFieldsTemplateService - found template /patchCase/description/input
It contains:
<f:field bean="Case" property="description">
<g:textArea name="description" cols="40" rows="5" maxlength="5000" value="some default text"/>
</f:field>
However I get
ERROR errors.GrailsExceptionResolver - NotReadablePropertyException occurred when processing request: [GET] /M3PatchManage/patchCase/create
Invalid property 'description' of bean class [java.lang.String]: Bean property 'description' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?. Stacktrace follows:
Message: Error processing GroovyPageView: Error executing tag <g:form>: Error executing tag <f:all>: Error executing tag <f:field>: Invalid property 'description' of bean class [java.lang.String]: Bean property 'description' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
Can any one describe how to use the customisation of fields or give a link with a good description (plugin doc is very thin)?
I'm on Grails 2.4.

I think your problem is the bean="Case" attribute. It seems the fields plugin is trying to render properties of the String "Case" rather than an instance of the Case class.
You should instead pass either the model key name of a Case instance, or the instance itself to this attribute. I would guess either of the following might work: bean="case" or bean="${case}".
Here's a Grails app of mine that makes extensive use of the fields plugin. Some example fields plugin templates are here and here's a form that uses them.
You'll notice that in almost all cases, an input field is passed as the body of the f:field tag, e.g.
<f:field bean="competition" property="code" label="Code">
<g:textField name="${property}" value="${value}" class="input-xlarge" maxlength="191"/>
</f:field>
This could be expressed more concisely as:
<f:field bean="competition" property="code" label="Code"
input-class="input-xlarge" input-maxlength="191"/>

I've been through the same issue. Try to use bean="${class}" instead of bean="class".
On "class" put the name of the class that you are trying to bean

Related

Flask Swagger documentation query parameter GET required

I'm using Swagger documentation with my flask project to document the endpoints and parameters.
To define the query parameters for an endpoint I'm doing:
#api.doc(params={
'name_query_parameter': 'Description'})
I wanted to know if it's possible for that parameter to show in the docs as "required", like it does for when the parameter is part of the path (home/name_query_parameter/something/something).
Looking into the documentation I only found the following:
#api.expect()
#api.doc(body=the_defined_payload)
But this implies for the information to be on the body, I can't have that with a GET request. Plus, I want it as a query parameter, not as part of the payload.
Is this possible at all?
Thanks.
The final solution to this is as follows, thanks to Mikhail for commenting about the parser. I have to admit though, documentation is not the best for flask-restplus.
I used the params part to make sure the fields appear in the docs along with a description and the parser for custom validation and to make the field appear as required even though it is located in the URL as params.
parser = reqparse.RequestParser()
parser.add_argument('superimportant',
type=inputs.boolean, location='args', required=True)
parser.add_argument('something', type=custom_validation_parser, location='args')
class MySuperClassResource(Resource):
#api.doc(parser=categories_by_retailer_parser,
params={"superimportant": "Description of this important field",
"something": "bla bla"
})
def get(self, blable):
parser.parse_args()
pass
The custom_validation_parser is just a method that allows custom validation, like for empty values. The format of that method is as follows. (It must return the value you want to access, and if there's . problem, raise a ValueError).
def custom_validation_parser(value):
if not value:
raise ValueError("Must not be empty.")
return value

Find the class name of a relation from the instance of a model in ember JS

I have foo an instance of the ember-data model thing. thing.js has the following property :
owner: DS.belongsTo('user')
If I have foo with an empty owner, how can I, with only foo and the 'owner' string, retrieve the value 'user' representing the model of the owner relation?
EDIT: I want to allow my select-relation component to works with relations where the name is different from the class name
It sounds like you have some work to do to finish setting up your relationships. Have a read through this page of the guides.
If the relationships are set up correctly, to get the associated user, you should be able to do foo.owner. This assumes that users are already present in the store. I recommend using the Ember Inspector browser plugin to debug the relationships.
This looks like a use case for typeForRelationship.
In your example you should be able to do something like
store.modelFor('thing').typeForRelationship('owner', store);
If you don't like that approach you can use the belongsTo reference API, where you use the meta data from the relationship to get the type
foo.belongsTo('owner').type
The only thing with that approach is that the type property may not be public API and possible (though unlikely) to change at some point.
It seems I can do the following :
this.get('model').get('_internalModel._relationships.initializedRelationships.'+this.get('relation')+'.relationshipMeta.type')
model being an instance and relation the string of the relation name, it correctly return the model of the relation.
EDIT : a better solution not using private API courtesy from the ember discord :
function getRelatedModelName(record, relationName){
let ParentModelClass = record.constructor;
let meta = get(ParentModelClass, 'relationshipsByName').get(relationName);
return meta.type;
}

How to make attribute_names list all attribute names in a document with dynamic attributes

I have a Rails 4.2 application with mongoid in which I'm importing csv files with test results. I can't define all fields in the model because they change from test to test and theres always around 700 of them. I use Dynamic Attributes and importing and displaying works fine.
I'm trying to use attribute_names method to get all attribute names but all I get is those defined in the model. If I don't define anything in the model it comes back with "_id" only. attributes method on the other hand can see attributes in the actual document on the other hand.
>> #results.first.attributes.count
=> 763
>> #results.first.attribute_names
=> ["_id"]
I also tried fields.keys, same problem
>> #results.first.fields.keys
=> ["_id"]
My model at the moment looks like this
class Result
include Mongoid::Document
include Mongoid::Attributes::Dynamic
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
Result.create! row.to_hash
end
end
end
Can somebody explain how to make it work?
Any help greatly appreciated.
This part is not very clear in the documentation.
and this answer doesn't address how you can make your case works ( I really don't know)... but it has one monkey patch at the end...
all I know is why this case not working...
as the documentation states
When dealing with dynamic attributes the following rules apply:
If the attribute exists in the document, Mongoid will provide you with your standard getter and setter methods.
For example, consider a person who has an attribute of "gender" set on the document:
# Set the person's gender to male.
person[:gender] = "Male"
person.gender = "Male"
# Get the person's gender.
person.gender
this is not your case... cause as it appears you are not defining any attributes in your model...
what applies in your case (from the code you showed and problem you described)
If the attribute does not already exist on the document,
Mongoid will not provide you with the getters and setters and will enforce normal method_missing behavior.
In this case you must use the other provided accessor methods: ([] and []=) or (read_attribute and write_attribute).
# Raise a NoMethodError if value isn't set.
person.gender
person.gender = "Male"
# Retrieve a dynamic field safely.
person[:gender]
person.read_attribute(:gender)
# Write a dynamic field safely.
person[:gender] = "Male"
person.write_attribute(:gender, "Male")
as you can see... there is no way for mongoid to add the setter and getter methods in runtime...
Monkey Patch
you could add a field (maybe string, array, hash, whatever suites you) to the document (attribute exists in the document)
on populating the document from the CSV row.. just save what are the fields of the CSV in that field... (hold the CSV keys in it)
use your predefined field (that holds the keys) instead of using .keys.
code example in your case.
class Result
include Mongoid::Document
include Mongoid::Attributes::Dynamic
field :the_field_that_holds_the_keys, type: Array
# ...
end
and in your controller:
#results.first.some_attribute
#=> method missing error
#results.first[:some_attribute]
#=> some_value
#results.first.the_field_that_holds_the_keys
#=> [:some_attribute, :some_other_attribute, :yada]

Rails: Invalid single-table inheritance type error

So, I am working on migrating this php site with an existing database which I cannot change over to Rails. There is a table: Quotes with a column named type. Whenever I try and create a model of this and set the type, it tells me the following error:
ActiveRecord::SubclassNotFound (Invalid single-table inheritance type: HOME is not a subclass of Quotes)
I don't understand why it thinks its inheriting because it's not supposed to. My create method looks like this:
quote = Quotes.create(
agent_id: agent.id,
client_id: client.id,
type: 'HOME',
status: 0,
date_created: DateTime.now
)
If I comment out the type, everything works fine. But with the Type it errors.
I resolved this by setting the models inheritance_column to nil. Active Record Models can inherit from a table through the attribute :type, setting the inheritance_column to nil removes that attribute allowing you to have a database column named type
class Quote < ActiveRecord::Base
self.inheritance_column = nil
end
I hate having potential gotchas deep in the code especially in the intial processes like generating a model. Better to just change the reserved word to something else and free yourself up to take advantage of inheritance column later if the need comes up. A cleaner solution is listed here -> rename a database column name using migration
It reads;
Execute $> rails generate migration ChangeColumnName
where, ChangeColumnName is the name of our migration. This can be any name.
Now, edit the generated migration file at db/migrate/_change_column_name.rb
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
$> rake db:migrate
You will have to edit controller and view files e.g. if the model name is Product then you will likely edit these files
/app/views/products/_form.html.erb
/app/views/products/show.html.erb
/app/controllers/products_controller.erb
/app/views/products/index.html.erb

Django KeyError when getting an object with a keyword for a field name

I wish to get an object in the following fashion:
Collection.objects.get(name='name', type='library', owner=owner, parent=parent)
Unfortunately type is a keyword as thus creates the following error:
KeyError at /forms/create_library
type
Is there a way to disambiguate the meaning of the word type to allow me to specify a field of that name?
Not tested:
Collection.objects.filter(
name__exact='name',
type__exact='library',
owner__exact=owner,
parent__exact=parent)
Query docs: http://docs.djangoproject.com/en/dev/topics/db/queries/
Also consider naming your field differently, mainly not with the same name as a builtin.
OK it turns out the problem was elsewhere. I was doing this in a form and thus using the self.cleaned_data dictionary of input values.
I was attempting to retrieve self.cleaned_data['type'] where in my previous simplification I stated the string 'library'. This was not in fact in the cleaned data of the form and thus threw a KeyError.