i have some logic to code in my model to calculate the number of business days between 2 dates input by the user.
In my view i would like to display the same number of business days before the user submits the action...
Is there a way to do this without duplicating code? I'd rather avoid an AJAX request (as it seems a bit overkill for th开发者_如何学Pythonat).for your help p.
Well this is a very good question because rewriting code in 2 different languages is not very DRY to say the least.
This problem happens very often especially for validations that SHOULD be done on the client to provide instant feedback, and MUST be done on the server for security purposes.
On the client side you do not have the choice for the language and have to use JavaScript. This implies that if you want to reuse your code you will have to have at least a JavaScript version.
One option is to use HotRuby http://hotruby.yukoba.jp/ to run a (large) subset of Ruby directly in the client. Interestingly enough this is very efficient: http://ejohn.org/blog/ruby-vm-in-javascript/ and should therefore suit your needs. Similarly RubyJS http://www.ntecs.de/projects.html converts Ruby code to JavaScript. Another one is rb2js http://rb2js.rubyforge.org/.
Another option is to run a JavaScript interpretor on your server, using the SpiderMonkey engine http://www.mozilla.org/js/spidermonkey/ or the v8 engine: http://code.google.com/p/v8/ both of which are very efficient.
Finally you could convert JavaScript to Ruby using RKelly: http://tenderlovemaking.com/2007/04/15/converting-javascript-to-ruby-with-rkelly/.
I believe the first option is easier to implement and will please most Rails programmers as one only writes Ruby code. The second option might be more efficient on the client but at the cost of other inefficiencies on the server. The third option might be the most efficient and will appeal more to JavaScript programmers or to reuse existing JavaScript code.
Although this goes beyond the original question (which is about Rails), I would also like to point out the JavaScript MVC http://javascriptmvc.com/ which prevents this problem altogether. Sometimes the solution to a problem is to remove the problem.
Since you want to avoid a server trip , you can put that logic ( that does the calculation ) on the client side in a javascript and call that after taking the input from the user .
Keep the two implementations together.
class BusinessDaysCalculator < MultiTierLogic
def ruby
#whatever
end
def js
"/*whatever*/"
end
end
If you want to calculate it in the front end, you'll have to create a separated function (or do an Ajax call).
You could however share some information between your two functions. For instance:
def business_days_whatever
business_days = ["monday","tuesday"]
// do stuff
end
Move business_days into a Constant.
def business_days_whatever
business_days = Constants::BUSINESS_DAYS
// do stuff
end
Then in the javascript you can do
function business_blah(){
vat days = <%= Constants::BUSINESS_DAYS.to_javascript_array%>;
}
I don't think it's worth not duplicating the code here- you are implementing it in two different languages. I do something similar in a .Net client that uses the webservice of my Rails app. Of course, I haven't seen your business days code...
Second, it's ridiculously easy to do AJAX in Rails, so I don't consider that overkill.
<%= observe_form 'form-id',
:url => { :action => 'business_days' },
:update => 'business-days'
%>
精彩评论