multilingual mongodb mongomapper - ruby-on-rails

I have a category collection and each category has a array of hashes containing attributes names and units to create a inout form with, to add a product of that category.
for example category car fields - {name : length, unit : mm}, {name : weight, unit : kg}.
Problem is i would this site to be multi-lingual and therefore need to store the field names per language.
I could put them inline :
for example category car fields - {en-name : length, cn-name : ....., de-name : ....., unit : mm}
Is there a better way ?
Not sure if this is best way as i want to be able to pass a docuement of names needing to be translated to the translator for all field names for all categories, so storing this way i would have to grab all then put into another docuement then translate and inset new translated naes back!!!
Any help or ideas ?
Thanks
rick

The best way would be to put translations in locale files (in config/locales/). For example (english locale):
en:
categories:
car:
length: Length
And then something like that when displaying name of the field:
I18n.t("categories.#{category.name}.#{field_name}")
This way you can maintain only one locale file and send the other ones to the translator.

Model translation is fairly easy in MongoDB.
Here's a gist that uses a custom MongoMapper type to transparently handle localization: https://gist.github.com/828114
Your LocalizedString would look like
name: {
en: '...',
cn: '...',
de: '...'
}
The custom type just stores/returns the value for the current I18n.locale

Related

Multiple values selection in <g:select> error

I'm trying to use multiple values for a select using <g:select multiple='true'>, but when i try to save the form to the DB, i got this error
Property [Languages] of class [class com.Myapp.hr.EmploymentSeeker] with value [french,english] is not contained within the list [[french, english, russian, chinese]]
here is my Domain:
class EmploymentSeeker {
Set<String> languages = [] as Set
static hasMany = [ languages: String ]
static constraints = {
languages(nullable:true,inList:Holders.config.languages)
}
}
Config file :
languages=[
'french',
'english',
'russian',
'chinese'
]
GSP:
<g:select multiple="true" name="languages" from="${employmentSeekerInstance.constraints.languages.inList}" value="${employmentSeekerInstance?.languages}" valueMessagePrefix="empSeeker.languages" noSelection="['': '']"/>
what may cause this error ?
As mentioned in Grails doc:
inList: Constrains a value so that it must be contained within the given list.
The problem is that your inList constrant it's a list of Strings, but languages from EmploymentSeeker isn't a String, it's a Set.
If it was a String, it would work, for example:
'french' is contained in ['french','english','russian','chinese']
But you have a Set, so
['french'] isn't contained in ['french','english','russian','chinese']
To make it work with inList you have to set in the constraint list all the combinations that user could choose, like:
[['french'], ['french', 'english'], ['english', 'french'] ...] and so on.
This answer describes how to archive those combinations, but actually it's not a good solution, because subsequences() doesn't care about permutations. However, adding permutations will increase your constraint list exponentially after growing of languages list.
As you can see, using inList is not a good solution in your case.
I would recomment to implement your custom simple constraint, like this:
languages(nullable:true,validator: {value, object ->
Holders.config.languages.containsAll(value)​​​)​
})
You can read about custom constraints here and here

Rails How to assign multiple values to an attribute

I`m begginer in rails, so I am not even sure if this is possible, if not please write it to me.
My goal is to write a search function to search through db.
The form is based on the check_box_fields which sends two arrays clan and class. And then it search thorough a db. But I don`t know how to set more then one attribute value to record.
Search engine:
def self.school_search(clan, class)
School.where(clan: clan, class: class)
end
and in my seed file I created few objects:
schools = [
{ nazwa: "Smok Bushi",
clan: "Smok",
class: "Bushi"
},
{ nazwa: "Pajak Bushi",
clan: "Pajak",
class: "Bushi", "Shugenja"
}
]
schools.each do |school|
School.create(school)
end
Everything is well when I search for object one I send params clan: "Smok" and class "Bushi" and object is selected. But I want the second object to be found by either clan: "Pajak" class: "Bushi" or clan: "Pajak" class: "Shugenja". I tried to pass this value as an array but it didn`t help.
Edit: used english names for attributes
You can, actually, pass an array to the attribute, as you said. So maybe you're doing something else wrong.
Active Records' Documentation is clear about that (read the "conditions" sub-section).
Edit: Adding example code for clarification
# This works
Model.where(title: ['Hello', 'Rails'])
You can not assign multiple value for one attribute. Maybe you should create association school has many klasa and klasa belongs to school.
P.s. it is desirable to use english words instead of polish(klasa = class)

How to customize json output from controller in rails

I have a controller that returns a list of categories and a count of items in each category
Category.joins(:item).group([:category_id,:name]).count
I would like to clean up the json formatting from this
(which is category_id, :name, :count )
{"[10, \"Fruit.\"]":2,"[11, \"Vegetables.\"]":1,"[2, \"Pasty.\"]":1}
to this
{"categoryitemcount":[ {"id":10,"name":"Fruit","count":7}]}
so a custom root name along with named columns
thanks in advance!
The solution to this is demoed in Railscast #219. Basically create a model not backed by a database and which represents the data you want to send back. In my case CategoryItemCount.rb (id, name, count). I built an array of these on the fly using the query given above, and output as json.

How can I create friendly URLs with MongoDB/Node.js?

For example suppose in designing a blog application I want something like
domain.com/post/729
Instead of
domain.com/post/4f89dca9f40090d974000001
Ruby has the following
https://github.com/hakanensari/mongoid-slug
Is there an equivalent in Node.js?
The id in MongoDB is actually a hexadecimal value to convert that into a numerical value you can use the following code to search for numerical value in the database like 1, 2, 3.. and this code will convert that value into appropriate hex
article_collection.db.json_serializer.ObjectID.createFromHexString(id)
where article_collection is your collection object
There are a few ways :
1- Assuming you are trying to provide a unique id to each blog post .
Why not overwrite the '_id' field of your documents in the blogs collection ?
Sample document would be :
{ "_id" : 122 , "content" : { "title: ..... }
You will have to look out for a method to generate an autoincrement id though, which is pretty easy.
This type of primary keys are however not recommended.
http://www.mongodb.org/display/DOCS/How+to+Make+an+Auto+Incrementing+Field
2- Let the _id field remain as it is, and additionaly store a key 'blogid' which is an integer, you will have to run ensureIndex on 'blogid` field though to make access by blogid fast. Storage overhead would be minor, as you will be storing a keyname and an integer more in your document.
Sample document would be :
{ "_id" : xxxxxxxxxx ,"blogid" : 122, "content" : { "title: ..... }
There are a bunch of different projects on GitHub like https://github.com/dodo/node-slug and https://github.com/stipsan/String.Slugify.js but they focus on making valid URLs out of strings (usually the post subject or article title). I haven't seen any that take a random number and some how produce a shorter random (?) and unique number.
Personally I just have a token field on my post object that contains a unique value that is shorter than just using the DB id directly (and a tiny bit more secure). If you are using Mongoose, the token can be generated automatically by hooking the pre 'Save' event on your Mongoose model.

Language-specific value in grails inList constraint

Users of my application have the possibility of choosing some values from list. The values for that list are in simple domain class, Foo, which looks like that:
class Foo{
String name
static mapping = {
id name: 'name', generator: 'assigned'
version: false
}
}
Foo looks the same for every language my app uses. In another class I have a constraint saying that Bar must be in list of Foo. Sometimes user doesn't know what to choose, so he may choose something like "I'm not sure" (so this option should be in list to to meet the inList constraint). Thing is, "I'm not sure" is written differently in different languages. How can I append this value based on current messages to inList constraint?
In your controller you could do:
def theList = foo.list().name // Get any array of strings.
// If you actually need > 1 field then you probably need to
// put the g.message below in a map
theList << g.message(code:"im.not.sure")
I don't believe inList constraint will help you here - it's designed for a simpler use case than yours.
I'd add a method to the class getLanguages() that handles this, and then since you seem to be interested in validation, write a custom validator to make sure right values are saved.

Resources