Complete name instead of database record value - symfony1

I have a database column that stores ENUM values, in this case I have a or i which means active or inactive. How, in admin-generator module, can I display Active / Inactive instead of a / i? Any help?
Edit: Display the Active or Inactive in index
What I have now is as follow:
ID Name Active Actions
1 Val1 a Edit | Delete
2 Val2 a Edit | Delete
3 Val3 i Edit | Delete
What I want to achieve is this:
ID Name Active Actions
1 Val1 Active Edit | Delete
2 Val2 Active Edit | Delete
3 Val3 Inactive Edit | Delete
Or just write a image_tag() depending on values something like checked.png when value is a or unchecked.png when value is i.

Where and what you want to change is very vague, but here goes :
In index page, just use a partial to override the displayed value via generator.yml. See symfony doc
Otherwise, in form pages, create another form, edit the sfWidgetFormChoice to have the wanted label. Then update the form class used in the module also via generator.yml. See symfony doc

Related

Auto-assigning objects to users based on priority in Postgres/Ruby on Rails

I'm building a rails app for managing a queue of work items. I have several types of users ("access levels") to whom I want to auto-assign these work items.
The end goal is an "Auto-assign" button on one of my views that will automatically grab the next work item based on a priority, which is defined by the users's access level.
I'm trying to set up a class method in my work_item model to automatically sort work items by type based on the user's access level. I am looking at something like this:
def self.auto_assign_next(access_level)
case
when access_level = 2
where("completed = 'f'").order("requested_time ASC").limit(1)
when access_level > 2
where("completed = 'f'").order("CASE WHEN form='supervisor' THEN 1 WHEN form='installer' THEN 2 WHEN form='repair' THEN 3 WHEN form='mail' THEN 4 WHEN form='hp' THEN 5 ELSE 6 END").limit(1)
end
This isn't very DRY, though. Ideally I'd like the sort order to be configurable by administrators, so maybe setting up a separate table on which the sort order is kept would be best. The problem with that idea is that I have no idea how to pass the priority order on that table to the [postgre]SQL query. I'm new to SQL in general and somewhat lost with this one. Does anybody have any suggestions as to how this should be handled?
One fairly simple approach starts with turning your case statement into a new table, listing form values versus what precedence value they should be sorted by:
id | form | precedence
-----------------------------------
1 | supervisor | 1
2 | installer | 2
(etc)
Create a model for this, say, FormPrecedences (not a great name, but I don't totally grok your data model so pick one that better describes it). Then, your query can look like this (note: I'm assuming your current model is called WorkItems):
when access_level > 2
joins("LEFT JOIN form_precedences ON form_precedences.form = work_items.form")
.where("completed = 'f'")
.order("COALESCE(form_precedences.precedence, 6)")
.limit(1)
The way this works isn't as complicated as it looks. A "left join" in SQL simply takes all the rows of the table on the left (in this case, work_items) and, for each row, finds all the matching rows from the table on the right (form_precedences, where "matching" is defined by the bit after the "ON" keyword: form_precedences.form = work_items.form), and emits one combined row. If no match is found, a LEFT JOIN will still emit a row, but with all the right-hand values being NULL. A normal join would skip any rows with no right-hand match found.
Anyway, with the precedence data joined on to our work items, we can just sort by the precedence value. But, in case no match was found during the join above, that value will be NULL -- so, I use COALESCE (which returns the first of its arguments that's not NULL) to default to a precedence of 6.
Hope that helps!

Return only results based on current object for dynamic menus

If I have an object that has_many - how would I go about getting back only the results that are related to the original results related ids?
Example:
tier_tbl
| id | name
1 low
2 med
3 high
randomdata_tbl
| id | tier_id | name
1 1 xxx
2 1 yyy
3 2 zzz
I would like to build a query that returns only, in the case of the above example, rows 1 and 2 from tier_tbl, because only 1 and 2 exist in the tier_id data.
Im new to activerecord, and without a loop, don't know a good way of doing this. Does rails allow for this kind of query building in an easier way?
The reasoning behind this is so that I can list only menu items that relate to the specific object I am dealing with. If the object i am dealing with has only the items contained in randomdata_tbl, there is no reason to display the 3rd tier name. So i'd like to omit it completely. I need to go this direction because of the way the models are set up. The example im dealing with is slightly more complicated.
Thanks
Lets call your first table tiers and second table randoms
If tier has many randoms and you want to find all tiers whoes id present in table randoms, you can do it that way:
# database query only
Tier.joins(:randoms).uniq
or
# with some ruby code
Tier.select{ |t| t.randoms.any? }

Implementing dynamic methods in rails for key/value pair

Let's say I have a database table called 'options' with corresponding model called Option. Structure of this table is simple and as follows ...
id -> primary key, auto increment
name -> key
value -> value for the key
Sample data rows could be as follows ...
id name value
---- ---------------------------- -----------
1 default_view DAILY
2 show_registration_number 0
3 notification_method IMMEDIATE
What I want is that all the options (keys) should be accessible to me as the method names.
For example if do as following ...
#options = Options.find(:all)
is it possible to access the data like #options.default_view which should return me the value as 'DAILY' and similarly #options.show_registration_number which should return the value as 0.
Also if that is possible, whether modification would be permissible like if #options.default_view = 'MONTHLY' and should update the corresponding record in the database.
This will get you almost the answer you were looking for: http://code.dblock.org/how-to-define-enums-in-ruby
It relies on const_missing and assumes that elements of your "enum" are defined as constants, in your case Option::default_view
However, it is easy to see how to adapt this code to use method_missing so that you can do Option.default_view
Another example of this same approach is contained in rails-settings gem, so you can browse this code for the answer you are looking for

How to select table column names in a view and pass to controller in rails?

So I am new to Rails, and OO programming in general. I have some grasp of the MVC architecture. My goal is to make a (nearly) completely dynamic plug-and-play plotting web server. I am fairly confused with params, forms, and select helpers.
What I want to do is use Rails drop downs to basically pass parameters as strings to my controller, which will use the params to select certain column data from my database and plot it dynamically. I have the latter part of the task working, but I can't seem to pass values from my view to controller.
For simplicity's sake, say my database schema looks like this:
--------------Plot---------------
|____x____|____y1____|____y2____|
| 1 | 1 | 1 |
| 2 | 2 | 4 |
| 3 | 3 | 9 |
| 4 | 4 | 16 |
| 5 | 5 | 25 |
...
and in my Model, I have dynamic selector scopes that will let me select just certain columns of data:
in Plot.rb
class Plot < ActiveRecord::Base
scope :select_var, lambda {|varname| select(varname)}
scope :between_x, lambda {|x1,x2| where("x BETWEEN ? and ?","#{x1}","#{x2}")}
So this way, I can call:
irb>>#p1 = Plot.select_var(['x','y1']).between_x(1,3)
and get in return a class where #p1.x and #p1.y1 are my only attributes, only for values between x=1 to x=4, which I dynamically plot.
I want to start off in a view (plot/index), where I can dynamically select which variable names (table column names), and which rows from the database to fetch and plot. The problem is, most select helpers don't seem to work with columns in the database, only rows.
So to select columns, I first get an array of column names that exist in my database with a function I wrote.
Plots Controller
def index
d=Plot.first
#tags = d.list_vars
end
So #tags = ['x','y1','y2']
Then in my plot/index.html.erb I try to use a drop down to select wich variables I send back to the controller.
index.html.erb
<%= select_tag( :variable, options_for_select(#plots.first.list_vars,:name,:multiple=>:true) )%>
<%= button_to 'Plot now!', :controller =>"plots/plot_vars", :variable => params[:variable]%>
Finally, in the controller again
Plots controller
...
def plot_vars
#plot_data=Plot.select_vars([params[:variable]])
end
The problem is everytime I try this (or one of a hundred variations thereof), the params[:variable] is nill.
How can I use a drop down to pass a parameter with string variable names to the controller?
Sorry its so long, I have been struggling with this for about a month now. :-( I think my biggest problem is that this setup doesn't really match the Rails architecture. I don't have "users" and "articles" as individual entities. I really have a data structure, not a data object. Trying to work with the structure in terms of data object speak is not necessarily the easiest thing to do I think.
For background: My actual database has about 250 columns and a couple million rows, and they get changed and modified from time to time. I know I can make the database smarter, but its not worth it on my end. I work at a scientific institute where there are a ton of projects with databases just like this. Each one has a web developer that spends months setting up a web interface and their own janky plotting setups. I want to make this completely dynamic, as a plug-and-play solution so all you have to do is specify your database connection, and this rails setup will automatically show and plot which data you want in it. I am more of a sequential programmer and number cruncher, as are many people here. I think this project could be very helpful in the end, but its difficult to figure out for me right now.

Rails custom meta model?

I'd like to be able to add "meta" information to a model, basically user-defined fields. So, for instance, let's imagine a User model:
I define fields for first name, last name, age, gender.
I would like users to be able to define some "meta information", basically to go in their profile page and share other information. So one user might want to add "hobbies", "occupation", and "hometown", and another might want to add "hobbies", and "education".
So, I'd like to be able to have a standard view for this kind of stuff, so for instance in the view I might do something like (in HAML):
- for item in #meta
%li
%strong= item.key + ":"
= item.value
This way I can ensure that the information is consistently displayed, rather than just providing a user with a markdown textbox that they may format all different ways.
I'd also love to be able to click on meta and see other users who have given the same thing, so in the example above both users defined "hobbies", it would be nice to be able to say I want to see users who have shared hobbies -- or even better I want to see users whose hobbies are ___.
So, since I don't know what fields users will want to define in advance, what kind of options are there for providing that kind of functionality?
Is there a gem that handles custom meta information on a model like this, or at least sort of similarly? Has anyone had experience with this kind of problem? If so, how did you solve it?
Thanks!
The dynamic field implementation depends upon following factors:
Ability to dynamically add attributes
Ability to support new data types
Ability to retrieve the dynamic attributes without additional query
Ability to access dynamic attributes like regular attributes
Ability query the objects based on dynamic attributes. (eg: find the users with
skiing hobbies)
Typically, a solution doesn't address all the requirements. Mike's solution addresses 1, and 5 elegantly. You should use his solution if 1 & 5 are important for you.
Here is a long solution that addresses 1,2,3, 4 and 5
Update the users table
Add a text field called meta to the users table.
Update your User model
class User < ActiveRecord::Base
serialize :meta, Hash
def after_initialize
self.meta ||= {} if new_record?
end
end
Adding a new meta field
u = User.first
u.meta[:hobbies] = "skiing"
u.save
Accessing a meta field
puts "hobbies=#{u.meta[:hobbies]}"
Iterating the meta fields
u.meta.each do |k, v|
puts "#{k}=#{v}"
end
To address the 5th requirement you need to use Solr Or Sphinx full text search engines. They are efficient than relying on DB for LIKE queries.
Here is one approach if you use Solr through Sunspot gem.
class User
searchable do
integer(:user_id, :using => :id)
meta.each do |key, value|
t = solr_type(value)
send(t, key.to_sym) {value} if t
end
end
def solr_type(value)
return nil if value.nil?
return :integer if value.is_a?(Fixnum)
return :float if value.is_a?(Float)
return :string if value.is_a?(String)
return :date if value.is_a?(Date)
return :time if value.is_a?(Time)
end
def similar_users(*args)
keys = args.empty? ? meta.keys : [args].flatten.compact
User.search do
without(:user_id, id)
any_of do
keys.each do |key|
value = meta[key]
with(key, value) if value
end
and
end
end
end
Looking up similar users
u = User.first
u.similar_users # matching any one of the meta fields
u.similar_users :hobbies # with matching hobbies
u.similar_users :hobbies, :city # with matching hobbies or the same city
The performance gain here is significant.
If each user is allowed to define their own attributes, one option might be to have a table with three columns: user_id, attribute_name, attribute_value. It might look like:
| user_id | attribute_name | attribute_value |
| 2 | hobbies | skiing |
| 2 | hobbies | running |
| 2 | pets | dog |
| 3 | hobbies | skiing |
| 3 | colours | green |
This table would be used for finding other users who have the same hobbies/pets/etc.
For performance reasons (this table is going to get large) you may want to maintain multiple places that the info is stored -- different sources of info for different purposes. I don't think it's bad to store the same info in multiple tables if absolutely necessary for performance.
It all depends on what functionality you need. Maybe it will end up making sense that each user has their key/value pairs serialized into a string column on the users table (Rails provides nice support for this type of serialization), so when you display info for a particular user you don't even need to touch the huge table. Or maybe you will end up having another table that looks like this:
| user_id | keys | values |
| 2 | hobbies, pets | skiing, running, dog |
| 3 | hobbies, colours | skiing, green |
This table would be useful if you need to find all users that have hobbies (run LIKE sql against the keys column), or all users that have anything to do with a dog (run LIKE sql against the values column).
That's the best answer I can give with the requirements you gave. Maybe there is a third-party solution available, but I'm skeptical. It's not really a "pop in a gem" type of problem.
In this case, I would at least consider a documentdb like mongo or couch, which can deal with this type of scenario much easier then an rdms.
If that isn't the case, I would probably end up doing something along the lines of what Mike A. described.

Resources