I just inherited a RoR 3.2 app and am trying to get it working on 4.2
I am going to put on my sarcastic hat for a second, just so I can feel better. Instead of having a single line in a single file to protect specific fields from mass-assignment, "Strong" Parameters requires bloating up controllers and heaven help you if a controller uses multiple models or a model is used by multiple controllers or need nested attribute whitelisting. This is the exact opposite of DRY and KISS.
That is better. Okay, so the question is, besides getting rid of mass assignment completely, which is sounding really good right about now, is there a sane way to use it or get around it. From what I understand that gem that brings back attr_accessible won't work in Rails 5 which is where this app is heading.
I understand the Ruby object model and can make a ton of modules that controllers can mixin, but that is just ugly and still error prone.
Any advice or hints would be welcome.
Why is that every new Rails feature involves more boilerplate spread over multiple files? If I wanted Java, I know where to find it. The stupidity of getting rid of the powerful and clean link_to_function in favor of using a tangled mess of callbacks almost made me quit, but adding that function back is trivial. Hopefully when the client wants the inevitable upgrade to Rails 5 I can talk him into something more sane and move things bit by bit to a sane web framework.
What you're after is "form objects". There's a great railscast episode on them. You may also be interested in the reform gem
Edit: looks like there's a free version of that railscast episode on youtube: https://www.youtube.com/watch?v=SvL_aZt3zyU
Related
I have generated a few controllers and models to my app and now I want to add testing (I know it's a little backwards but at least I am starting fairly early in my project). Anyway, every time I generated a controller/model I did not include the --no-test-framework so now I have a bunch of specs related to controllers, helpers, models, and views. Do I need these? And, if not, is it okay to just delete them? I am noticing from some tutorials (Hartl, Bates) that they are using request specs, are these all I need?
Thanks!
I am looking at a rails app and at the top of every controller there is a block of code that looks something like this
expose(:var) {Model.find params[:var_id]}
I understand what is inside the block just fine but...
I cannot find any documentation on what the expose function does where it comes from or anything I have tried searching the project and using the searchable rails docs.
I would love to know what it does, can someone please tell me or point me to the docs.
This is probably referencing the decent_exposure gem. You can learn more about it here: http://railscasts.com/episodes/259-decent-exposure
Source: https://github.com/voxdolo/decent_exposure
It's a method from the Decent Exposure gem. You can check out a screencast that Ryan Bates did on it over at Railscasts. It's a really great gem. I use it in my application. It cuts down on a lot of the redundancy in the controller layer.
expose is not a part of Rails, it comes from the decent_exposure gem.
It is not an answer to the question. I just want to make the Rails world a bit better and I hope that somebody will read this.
Please think twice before using expose. You should only use it if you 100% sure you are using it the right way and it really makes the code better. Read the documentation properly!
One of projects I worked on became unmaintainable because of tons of expose in controllers which replaced not only all #instance_variables passed to views, but also a lot of business logic and the most helper methods.
When you use expose it is not clear in which controller actions and in which views it is used. Unexperienced developers combine data and logic for multiple actions and multiple views in the same expose block.
That's a nightmare.
Believe me, expose really destroys projects if not used properly.
I have a game I wrote in Actionscript 3 I'm looking to port to iOS. The game has about 9k LOC spread across 150 classes, most of the classes are for data models, state handling and level generation all of which should be easy to port.
However, the thought of rejiggering the syntax by hand across all these files is none too appealing. Are there tools that can help me speed up this process?
I'm not looking for a magical tool here, nor am I looking for a cross compiler, I just want some help converting my source files.
I don't know of a tool, but this is the way I'd try and attack your problem if there really is a lot of (simple) code to convert. I'm sure my suggestion is not that useful on parts of the code that are very flash-specific (all the DisplayObject stuff?) and also not that useful on lots of your logic. But it would be fun to build! :-)
Partial automatic conversion should be possible, especially if the objects are just 'data containers', watch out for bringing too much as3-idiom over to objective-c though, it might not always be a good fit.
Unless you want to create your own (semi) parser for as3 you'd need some sort of a parser, apparently FlexPMD has one (never used it), and there probably are others.
After getting your hands on a parser you have to find some way of suggesting to the system what parts could be converted automatically. You could try and add rules to the parser/generator script for the general case. For more specific cases I'd use custom metadata on the actual class/property/method, assuming a real as3 parser would correctly parse those.
Now part of your work will shift from hand-converting files to hand-annotating files, but that might be ok for you.
Have the parser parse your classes and define actions based on your metadata that will determine what kind of objective-c class to generate. If you get this working it could at least get you all your classes, their simple properties and method signatures (getting the body of the methods converted might be a bit too much to ask but you could include it as a comment so you'd have a nice reference while hand-translating).
PS: if you make this into a one way process be very sure you don't need to re-generate it later - it would be bad if you find out that you have been modifying the generated code and somehow need to re-generate all those classes -- that would mean you'll have to redo all your hard work!
I've started putting a tool together to take the edge off the menial aspects of this process.
I'm trying to figure out if there's enough interest to make it clean and stable enough to release for others to use. I may just do it anyway.
http://meanwhileatthelab.blogspot.com.au/2012/08/automating-process-of-converting-as3-to.html
It's so far saving me a lot of time while porting one of my fairly large games from AS3 to objc.
Check out the Sparrow Framework. It's purported to be designed with Actionscript developers in mind, recreating classes that sort of emulate display list and things like that. You'll have to dive into some "rejiggering" for sure no matter what you do if you don't want to use the CS5 packager.
http://www.sparrow-framework.org/
even if some solution exists, note that architectural logic is DIFFERENT, and many more other details.
Anyway even if posible, You will have a strange hybrid.
I am coming back from WWDC2012, and the message is (as always..) performance anf great user experience.
So You should rewrite using a different programming model.
In Rails 2 I know of a few plugins for enumerations such as acts_as_enumeration and enumerate_by but they don't seem to be maintained or updated for Rails 3. Preferably, the solution would store the enum in memory rather than a database for performance reasons but really any method would be useful since it can always be cached.
I did find enumerated_attribute that claims to work with Rails 3 but quite honestly I don't like the API and was hoping for another good solution.
(Sorry for only linking to the one plugin but it won't let me post more than one link until I get a higher reputation)
I am currently using lwe's simple_enum which seems to be actively developed and stores values on memory or if you prefer on a table.
If you're using DataMapper as your ORM have a look at dm-types which includes an Enum type.
There is this gem, enumerate_it, it has good documentation and very well done!
This is more general question then language-specific, altho I bumped into this problem while playing with python ncurses module. I needed to display locale characters and have them recognized as characters, so I just quickly monkey-patched few functions / methods from curses module.
This was what I call a fast and ugly solution, even if it works. And the changes were relativly small, so I can hope I haven't messed up anything. My plan was to find another solution, but seeing it works and works well, you know how it is, I went forward to other problems I had to deal with, and I'm sure if there's no bug in this I won't ever make it better.
The more general question appeared to me though - obviously some languages allow us to monkey-patch large chunks of code inside classes. If this is the code I only use for myself, or the change is small, it's ok. What if some other developer takes my code though, he sees that I use some well-known module, so he can assume it works as it's used to. Then, this method suddenly behaves diffrent then it should.
So, very subjective, should we use monkey patching, and if yes, when and how? How should we document it?
edit: for #guerda:
Monkey-patching is the ability to dynamicly change the behavior of some piece of code at the execution time, without altering the code itself.
A small example in Python:
import os
def ld(name):
print("The directory won't be listed here, it's a feature!")
os.listdir = ld
# now what happens if we call os.listdir("/home/")?
os.listdir("/home/")
Don't!
Especially with free software, you have all the possibilities out there to get your changes into the main distribution. But if you have a weakly documented hack in your local copy you'll never be able to ship the product and upgrading to the next version of curses (security updates anyone) will be very high cost.
See this answer for a glimpse into what is possible on foreign code bases. The linked screencast is really worth a watch. Suddenly a dirty hack turns into a valuable contribution.
If you really cannot get the patch upstream for whatever reason, at least create a local (git) repo to track upstream and have your changes in a separate branch.
Recently I've come across a point where I have to accept monkey-patching as last resort: Puppet is a "run-everywhere" piece of ruby code. Since the agent has to run on - potentially certified - systems, it cannot require a specific ruby version. Some of those have bugs that can be worked around by monkey-patching select methods in the runtime. These patches are version-specific, contained, and the target is frozen. I see no other alternative there.
I would say don't.
Each monkey patch should be an exception and marked (for example with a //HACK comment) as such so they are easy to track back.
As we all know, it is all to easy to leave the ugly code in place because it works, so why spend any more time on it. So the ugly code will be there for a long time.
I agree with David in that monkey patching production code is usually not a good idea.
However, I believe that for languages that support it, monkey patching is a very valuable tool for unit testing. It allows you to isolate the piece of code you need to test even when it has complex dependencies - for instance with system calls that cannot be Dependency Injected.
I think the question can't be addressed with a single definitive yes-no/good-bad answer - the differences between languages and their implementations have to be considered.
In Python, one needs to consider whether a class can be monkey-patched at all (see this SO question for discussion), which relates to Python's slightly less-OO implementation. So I'd be cautious and inclined to expend some effort looking for alternatives before monkey-patching.
In Ruby, OTOH, which was built to be OO down into the interpreter, classes can be modified irrespective of whether they're implemented in C or Ruby. Even Object (pretty much the base class of everything) is open to modification. So monkey-patching is rather more enthusiastically adopted as a technique in that community.