I have been messing about with making a sortable table module thing. I know some might exist but want to get experience doing this myself. I had the idea of have it like so:
SortedTable.new(ModelName, Hash_Of_Columns_And_Fields, ID)
example
SortedTable.new(Post, {"Title" => "title", "Body" => "body", "Last Comment" => "comment.last.title"}, params[:id])
I am planning to do something like:
def initialize(model, fields, id)
data = {}
model = model.capitalize.constantize
model.find(id)
fields.each do |column, field|
data[column] = model.send(field)
end
end
This works fine for title and body but when it comes to getting the Last Comment with comment.last.title it errors out. I have tried doing Post.send("comments.last.title") but says NoMethodError: undefined method 'comments.last.title' for #<Post:0x0000010331d220>
I know I can do Post.send("comments").send("last").send("title") and that works but I can not think of how to do that dynamically by taking the fields and spliting the on . then chaining the sends. Can anyone give me advice on how to do this? If I am doing this completely wrong also then please say or point me in the direction of code that does something similar. I am not a expert ruby developer but I am trying.
P.S The above code might not work as I am not at a computer with ruby/rails to test, but hopefully you get the concept.
Cheers
first and dirtiest solution is
evalnext solution little more functional
PS
And your design is ugly
EDIT
The inject can be written more concisely as
field.split('.').inject(model, :send). And I’d strongly discourage theevalway — unnecessaryevalsare one more case where you can slip up and allow arbitrary code execution, and they’re also slow. (Also, I’m pretty sure that should just beeval("model.#{field}")— you don’t want to interpolate the string value ofmodel. Yet another example of how easy it is to slip up anevalexpression.) – @Chuck