|
I have three questions, but there's a wall o' text first. Background: I have to replace some existing apps that nobody likes with a Ruby on Rails web app. This app will have a back end API for other processes to send in data without going through the web pages. I'm vaguely aware of web services, and figured that would be the way to set up the API, assuming that it can be handled from the same rails server that is simultaneously handling the web app. I don't care whether I use a SOAP web service or a restful one (not entirely comfortable with the differences, but my requirements should be pretty simple database inserts and queries, so I imagine that can be done with either approach). I looked around, and it looks like the gems that let you plunk in web service functionality are old and not maintained, but that it's not supposed to be hard to do your own thing. Current: Working from this page, I made a GET route that can return just plain text in response to a request (which will probably be coming from curl commands in both R scripts and another Ruby script), and got a spot in my controller to render that text. I'll plan to use this to return completion codes and/or query results. I assume that setting up a post route will be similar, and that this is the way to return data to another process using the app. My questions: 1) The requests might be quite large, involving insertion of several related and linked database rows, and will need to be parsed and processed before returning a completion code. I want to have the user pass in some XML string, or maybe a JSON construct (unless there's a better option), but I have no idea how to get that data into the controller. Should it just be a url parameter of some sort, or is there a better way to get this done? Edit: I think I figured this one out - code:
2) Is this the right way to go about this, or should I be looking at some more formal web service setup, even if it uses outdated code? Or some other way of setting up the API entirely? 3) Ultimately, I want to restrict use to approved people, so random weirdos can't just post data to our database for fun and profit. Is there a standard way to enforce something like that? I assume we don't just want login and password data coming through GET/POST requests. Peristalsis fucked around with this message at 19:51 on Aug 20, 2013 |
# ¿ Aug 20, 2013 17:32 |
|
|
# ¿ Apr 27, 2024 11:35 |
|
Cocoa Crispies posted:1) Put a number on "large." Kilobytes? Megabytes? Gigabytes? Cocoa Crispies posted:2) Rails is a perfectly fine web service setup; Sinatra would work too, but past some complexity point I've always found myself wishing for Rails' structure. Cocoa Crispies posted:3) The easy way is to use Basic auth and HTTPS so that login and password data coming through GET & POST requests isn't unencrypted on the wire. kayakyakr posted:I would suggest making a standard rails app but instead of (or in addition to) html.erb files, write json.jbuilder views. Makes a pretty good web service endpoint. Thanks for the help. I feel better knowing that I'm not way off base trying to do it this way, and that just rendering non-HTML stuff is a way to return info to the calling code.
|
# ¿ Aug 20, 2013 20:05 |
|
Cocoa Crispies posted:What's "a page or more?" I'm going to assume it's under a few megabytes and jamming it in a POST body (that's not wrapped in form encoding) should work. I don't know exactly what the xml input will look like yet. We're not passing around the library of congress, but I expect that a worst case could be a text file of hundreds of lines. If I had more info, I'd give it to you. I thought I remembered that POST params are not limited in size, so that this should be a reasonable thing to pass around via HTTP. In any case, it seemed like a bad thing to put in a URL parameter. kayakyakr posted:For XML use Builder: kayakyakr posted:Don't use routing tricks, use the format parameter. Example: Thanks, I'll look into that, too. I don't think there will be an HTML version of most of the web services routes, but I'll definitely want to combine the XML and JSON in one place. Edit: I've probably been unclear - for the most part, I'll be reading the XML, and parsing it. I might pass back query results in XML, as well, but my main problem is passing the client's XML into my code and parsing it.
|
# ¿ Aug 20, 2013 21:24 |
|
kayakyakr posted:For XML use Builder: What am I missing here? This looks like a God-awful way to construct anything. I've seen it recommended in a couple of places, but the API seems horrible, and constructing nested XML is nigh on impossible. Is there a better set of instructions than the minimal examples on the github and rubyforge sites? I guess I assumed that using this would be easier than building up XML as strings in my code, but I'm not seeing that at all.
|
# ¿ Aug 26, 2013 16:56 |
|
Smol posted:The good thing about libraries like Builder and Nokogiri::XML::Builder is that the structure of the code mirrors the structure of the resulting xml. For example, Wait, do I have to use Nokogiri with Builder? I'm confused now - I thought they were alternate ways of doing the same things.
|
# ¿ Aug 26, 2013 17:35 |
|
Smol posted:They're different libraries. Nokogiri is a general purpose XML processing library which offers a Builder-like API for constructing XML documents as well. The big difference between Builder and Nokogiri::XML::Builder is that Nokogiri uses either libxml2 or a similar Java library under the hood, so it should be quite a bit faster. Okay, sorry if I'm being dense, but let me back up. I'd like nice libraries to more easily parse and construct XML strings (and if the same gem could do both, that's even better). Someone suggested the Builder gem, but I found it difficult to understand, and nearly impossible to use. I'd like to get a better explanation of how it works, or (if it does just suck) other alternatives. Are you suggesting that Nokogiri is better? Peristalsis fucked around with this message at 17:57 on Aug 26, 2013 |
# ¿ Aug 26, 2013 17:54 |
|
Smol posted:If I had to choose between the two, I'd use Nokogiri for XML generation. I've been using Ruby for over 6 months, intermittently with Rails. I like Ruby well enough, but I've always found the documentation to be lacking, at least in organization. For the current problem, I'll see if I can make Nokogiri do what I want, and forget about Builder for now. The main problems I was having with Builder were: 1) When trying things out in irb/Rails console, it appends an extraneous <inspect/> element - not the end of the world, but very distracting when I was trying to play with the tool to figure out what I was doing wrong. 2) I don't see a way to build up an XML string as I go along. I'm trying to model objects with a class hierarchy, and I had hoped to add elements and sub-elements to a single string/builder model as I looped over each collection. I really didn't want to have to make one huge instantiation call with every piece of information in it - keeping track of that would be far worse than building my own, simple xml generation routines in each class. 3) Getting nested elements and attributes to work without escape characters corrupting the end result was much, much harder than it needed to be. Edit: For my background, I've been programming professionally since 1997, but mostly with more traditional tools. I've used VB and Java the most, with some work in Matlab, Perl, C/C++, AREV, and some Pascal and Mumps. There's probably one or two others that I'm not thinking of. I've hacked at some javascript to debug issues at a previous job, but never approached it systematically or anything. Peristalsis fucked around with this message at 18:41 on Aug 26, 2013 |
# ¿ Aug 26, 2013 18:31 |
|
Baron Dirigible posted:Can someone please explain the difference between belongs_to: through: and has_and_belongs_to_many:? This guide says belongs_to: through: is better if I need to actually use the relationship model, whereas I don't have to with has_and_belongs_to_many -- but I need to remember to create the joining table. So, what's the difference? I'd assume if I were making a joining table I'd then be able to use the relationship model, as with belongs_to: through:, so where's the benefit of the latter choice? Is there any way for RoR to create the join table automatically? kayakyakr posted:You are correct. habtm does not have an associated model while hmt does. I was confused about this recently, too. Both habtm and hmt need and use a join table in the database, right - it's just that one doesn't use or require a corresponding Rails model? Also, you have to create the join table in both cases, don't you? I'm assuming that they only point it out in the habtm case because it would be easier to forget it, since you don't have a model for it to remind you of its existence.
|
# ¿ Sep 1, 2013 21:39 |
|
I'm really trying to use the built-in testing stuff for the new RoR project at work, and I can't figure out why it won't do what it's supposed to do. I've put a dummy test in a single model class's unit test, and I just want to run the drat thing. I've tried running this from rake, directly with ruby, with and without the -I switch (I probably have the wrong syntax for that) to capture 'test_helper', etc. The closest I come is when I get an error that a column isn't in a table. That's a true statement, but I've run a migration that deleted it, and I don't have a clue how or why the test still thinks it should be there. I'm doing development on my Windows machine, using SQLite3, if that matters. I have a Linux VM, but I'm waiting for our helpdesk to get with me to get the database set up on that appropriately, so for now, I'm stuck with Windows 7. So, here are my questions: 1) I just want to run a single file's tests - what is the syntax for that (including the -I switch, if I need it)? I just have the default rails directory structure, with a test directory below the main app directory, and test files stubbed in by the scaffolding. I've found lots of weird and inconsistent suggestions online, none of which work for me. The best single instruction set glosses over the switch. I've been trying things on the order of "rake test <my path and file>", and I sometimes throw in a "-I <directory>" for good measure. 2) For the -I switch, some of the sources I found seem to put quotes around the path, and not leave a space after the switch but before the path - is that right? 3) What testing method does this default rails project testing use? These look like Test::Unit tests, but just running them from the command line as such doesn't work. I don't think they're Rspec, since they don't look like that syntax, but I guess I could be wrong.
|
# ¿ Sep 9, 2013 19:45 |
|
Oh, and one more question. I think this came up with a one-to-many relationship between two models/tables, say owners and products (one owner can own many products). If I create a new product object, and add it to an owner like this "owner1.products << my_new_product_object", then I can see the product in the products array, the next time I execute "owner1.products". However, if I just manually set "my_new_product_object.owner_id = 1", then Rails doesn't add it to owner1.products, even though, as far as I know, the net effect should be exactly the same. Any idea what's going on here?
|
# ¿ Sep 9, 2013 20:34 |
|
Molten Llama posted:Unless you're working with a plain old Ruby object, you probably need a Rails environment anyway, so don't bother with running Ruby itself or worrying about the -I argument. Start with the standard rake test, then tack on TEST=path/to/test: Thanks. If I change that to code:
code:
Peristalsis fucked around with this message at 21:20 on Sep 9, 2013 |
# ¿ Sep 9, 2013 21:08 |
|
Cocoa Crispies posted:You have some fixtures that need updating (or rather, deleting and replacing with Factory Girl). Thanks - I didn't even know fixtures existed. I'm googling around, but not seeing any information on how to maintain them. Are migrations supposed to update fixtures automatically, or am I supposed to go change them by hand every time my data def changes? Is there a Rails command to recreate them all from scratch?
|
# ¿ Sep 10, 2013 14:47 |
|
Peristalsis posted:Oh, and one more question. kayakyakr posted:Did you reload owner1 between creating your new product object? Otherwise, it'll probably just cache the last products lookup. Are you use the product object is saving and are you sure that's the proper id? In case anyone is interested, I think the issue here was that I hadn't saved the model objects consistently, since I was just monkeying around in rails console. If I have owner1 linked to product1 as above, but haven't saved either of them, then owner1.products returns an array with product1 in it, but product1.owner doesn't return anything. I can't reload product1, presumably because it isn't in the database yet, so I think I just have to (carefully) save things before trying to use this particular voodoo.
|
# ¿ Sep 19, 2013 23:17 |
|
I have a weird issue. I added some code into my project from another developer, and now I'm getting a missing method error in one of the files he changed (though not directly related to his changes). The code runs fine on his box, on another developer's box, and on the test server. It's only my environment having a problem with it. I should note that the same line of code that is throwing the error now, was not throwing an error on my box previously. The error refers to a method in a gem that I've had loaded for some time. I've re-checked out the code, I've run bundle install, etc., but I'm still getting the error. My best guess is that something corrupted the gem in question on my computer. Is there a way to force rails to re-download that gem? Does anyone have any other thoughts or suggestions?
|
# ¿ Oct 14, 2013 16:06 |
|
Another weird issue. We have code:
code:
Edit: This wasn't an issue until the other developer implemented logins with the devise gem. So it's possible that there's actually an issue with that, or with its interaction with LDAP or with the CSRF protection. Peristalsis fucked around with this message at 21:29 on Oct 16, 2013 |
# ¿ Oct 16, 2013 19:10 |
|
We have a shiny new RoR app with a web interface and a webserivce API for backend access. I want to adapt an old Ruby script (no Rails) to use that API, but it'll be a lot easier if I can use some of the model classes from the web app to do some parsing and processing. This is a completely different app, running in a different directory (probably even on a different server). Is there a good way to import some of my ActiveRecord models from the Rails app to use in plain Ruby? I really don't want to re-write all the necessary logic.
|
# ¿ Nov 7, 2013 21:03 |
|
I have a download action in a controller that's giving me some trouble. The basic structure is this: code:
My problem is that, in some cases after a successful download, I want to refresh that calling screen to put a list of certain files at the bottom. I tried putting a redirect_to in the first if-block, but got an error that I can only use one render or redirect per action. I figured Rails just wasn't smart enough to realize that only one of them could be called, so I tried to move the existing redirect after the if-else-end block and fiddle with the parameters, but that also gave me the same multiple render/redirect error. So, I guess there must be an implicit render involved in the block with the send_to, but I don't know how to find, trace, or edit that. It doesn't seem to be using any actual view code, and rake routes shows me the route for getting into this download action, but I don't see anything that leads out of it to a view. I'm sure I'm missing something simple, but I'm not sure where to go from here.
|
# ¿ Jan 30, 2014 16:08 |
|
The Journey Fraternity posted:send_file is a 'renderer' here. Bummer. Is there any way to edit or add to what it does? Or another way to force a refresh of the calling page?
|
# ¿ Jan 30, 2014 18:23 |
|
Smol posted:It's not really possible to know if a file download has started or succeeded in JavaScript. Your best bet is to initiate the download via hidden iframe that links to the zip download url, setting a cookie in the zip response and polling for the cookie in your JS code. I don't think there's any JavaScript involved - this is all being done by http posts. I'm not worried at the moment about whether the download succeeds, I'm just trying to refresh the page that initiated the download after the send_file's render. Edit: KoRMaK posted:I swear I had to deal with something similiar but I kind of forget how. I think it involved using a javascript response. Don't send the file out via the first controller, but instead make the browser ajax request the file in your js response and then you can run a switch in the js response to see if it should do anything else. Ugh. This is all a bit beyond my expertise. Maybe I should just look for a way to send up a dialog or something with the file info for now. Peristalsis fucked around with this message at 18:36 on Jan 30, 2014 |
# ¿ Jan 30, 2014 18:30 |
|
Arachnamus posted:If you just want to display something after a download, you'd do better by putting it into the page that kicks off the download. I want the former, but I don't have the information to display until the app starts processing the files to download. It's a list of files that are too large to download over the web app, and I get that list by looking at the file type of all the files selected by the user. Until the user selects the files and submits the list, I don't know which files can be downloaded. However, I could just mark all the non-downloadable files on the page with an asterisk and footnote to begin with, to let the user know that those files will just have their network locations/paths listed in a text file instead. Maybe my boss will go for that. If not, his last suggestion was to render a separate confirmation page that listed which files will be downloaded and which won't, and make the user submit from that form to start the actual download. I think that'll work, too, but it's a lot more hassle, and might not be much easier than just learning all this JavaScript stuff. Thanks for the ideas!
|
# ¿ Jan 30, 2014 19:51 |
|
Arachnamus posted:You could also tag the files which are known to be too large using a data attribute or a CSS class, then use javascript to build the in-page list of files that won't be downloaded as the user is selecting them. kayakyakr posted:You can also use a redirector on the confirmation page if you don't have an absolute need to submit a post. To do this, when they hit download, you would send them to a download page and then use JS to open the download link 5 seconds later. Send the files as 'attachment' and they'll never leave the confirmation page. Thanks for the additional ideas. I don't care about posting or not posting, I'm just trying to get a fix out for this as quickly as possible (i.e. changing as little of the code and structure as I can at this point). For the next version, we'll want something better than my footnote though (my boss went for that idea, so I'm on to the next artificially induced crisis), so I'll try to look into integrating JavaScript and whatnot. I've been able to work primarily on the back end of this app, and now that I'm getting UI stuff thrown at me, I need to figure out what the hell I'm doing with HTML, css, and JavaScript.
|
# ¿ Jan 31, 2014 14:39 |
|
I think this will be an easy one, but I'm confused on how to use module functionality in different places of the app. I have a Utils module in /lib/app_name_utils.rb. In several controller routines, I have logger = Utils::SingletonLogger.get_logger. Sometimes these assignments work, sometimes they don't. In particular, one tester tells me that roughly half the time he goes to one of the index pages, it crashes. I've been doing some Googling, and I know I could use code:
code:
I'm also not clear if I have to load/require the module everywhere I use it, or just in one central place (for now, I've added config.autoload_once_paths += %W(#{config.root}/lib) to application.rb). And I found a statement online that claimed that the name of the file in which the module resides should match the name of the module, which I haven't done. Is that critical? Peristalsis fucked around with this message at 19:49 on Feb 4, 2014 |
# ¿ Feb 4, 2014 19:46 |
|
kayakyakr posted:Consider using the newly standardized concerns paradigm? Alas, we aren't using Rails 4, and I don't want to restructure this code that was supposed to go out two months ago any more than necessary. Edit: Let me streamline my questions. 1) Is it enough for the application just to require/load the file somewhere before its modules are included, or does it have to be loaded in every file in which it is used? 2) Once loaded, does its module have to be included in every file where it will be used, or is there some global include list? 3) Is the name of the file relative to the name of the module important? 4) Is there a way to access the module's code without including it? (E.g., using ModuleName::MethodName seems to work some of the time in test, and all the time in DEV. I must have found that somewhere....) 5) If I do include the module in a file, can I still specify the module from which it came when I call it, or do I have to call it without a prefix or module specification of any sort? I'd like to keep the module name included when it's used just for clarity. Peristalsis fucked around with this message at 22:17 on Feb 4, 2014 |
# ¿ Feb 4, 2014 20:51 |
|
I have a set of models that all need the same validation code (just checking a common field value against a controlled vocabulary). I'd prefer not to repeat this code in every one of the models. I created a mixin module for the vocabulary itself, but I don't think the validations can be in a mixin, can they? Is my best bet to put a new superclass with that validation between ActiveRecord and my models? Or should I not be sweating a single line of repeated validation code?
|
# ¿ Feb 28, 2014 15:52 |
|
I have a number of has_many :through relationships in the app I'm working on, and I want to keep the join tables from filling with junk. Say we have a Doctor model linked to a Patient model through an Appointment model. If I delete a patient, I naturally want to delete any appointments that patient has. I can do this using :dependent => :destroy in the models' links, like so:code:
We're using rails 3.2.1, if that matters.
|
# ¿ Mar 25, 2014 19:10 |
|
Smol posted:You'll want to read the "Deleting associations" section here. Thanks for the link - it turns out that I had read some bad info, and didn't keep reading to see it corrected. So, as I understand it: * There is no further shortcut - I need :dependent => :destroy for each linkage. * I can put the :dependent => :destroy on the has_many link to the join table, OR on the has_many, :through link to the other real table. Is one considered better than the other? For the previous example, that means choosing between these: code:
code:
|
# ¿ Mar 26, 2014 14:58 |
|
We have a Ruby on Rails app that uses Devise for logging in and out. I'm responsible for a backend XML API. Currently, users can use cURL commands to log in, update data, etc. I now need to enable an explicit logout capabitlity through the API, and I'm having trouble making it work. Every page of the UI has a logout link, and I just want to use cULR to simulate clicking that link. The logout sends a DELETE command to /users/sign_out, with an authenticity_token parameter. I've tried doing that with cURL, but I can't make it work. I've tried attaching the login cookie, and that didn't help. Do I need to get that authenticity token into the command data? If so, how do I do that? Would it be easier to make a new controller action and route to handle the POST/DELETE/whatever in code, so the user can just specify a URL?
|
# ¿ Jul 31, 2014 19:27 |
|
kayakyakr posted:Disable authenticity token for xhr calls. It makes no sense. I don't understand this response. I'm just looking for a command to log out via cURL. The authenticity token already isn't being checked in the controller that handles the API XML inputs, but right now I'm just trying to mimic what the logout link does (i.e. it doesn't use my code, it goes through the Devise stuff). Peristalsis fucked around with this message at 21:30 on Jul 31, 2014 |
# ¿ Jul 31, 2014 21:27 |
|
Lexicon posted:What's the best way to model ordering within a scoped set of records? The project I'm working on is, roughly speaking, a survey app - Question is a model, as is QuestionSet. Currently, each Question record has a position field that is unique scoped to a QuestionSet. This represents, as expected, the order of each question within the particular survey (QuestionSet). I think using large, non-adjacent integers is kind of an ugly hack, and in theory, it will only work until you do enough re-ordering to fill up one of the gaps. Have you considered giving each question a reference to the next question, instead of an absolute position? Then you're basically just maintaining a linked list. There may be (probably are) better ways, but I think even this is better than using huge counters.
|
# ¿ Aug 18, 2014 18:07 |
|
Arachnamus posted:What happens if two people reorder them at the same time? Or two people delete one? Sorry to necro this, but what do you mean? Are you basically concerned with record locking? If so, wouldn't that be an issue for any update method?
|
# ¿ Aug 19, 2014 14:34 |
|
Arachnamus posted:It's a concern for any update method, yeah, but especially for one which is trying to maintain a linked list. If you're doing a mass update then a user might blat another user's changes but at least they won't leave it in a totally broken and unrecoverable (from their interface) state. Thanks, that makes sense.
|
# ¿ Aug 19, 2014 16:01 |
|
I have a question about using AJAX in Rails. Here's some simplified code to illustrate my problem: In foobars_controller.rb code:
code:
I assumed I'd have to stuff the value of @other_var into an HTML element of some sort, then extract it with some JavaScript, but I'm not sure how to go about that. However, the only suggestion I've had so far involves chaining the ajax().done() method in conjunction with somehow getting a json document from the controller, but this doesn't really make any sense to me.
|
# ¿ Nov 6, 2014 22:27 |
|
A MIRACLE posted:If the value never changes, you can just insert it with <%= @my_var %> into javascript the same as HTML Well there's 3 hours of my life I'm never getting back. It turns out that this is an array variable (list of row id's). Is there a best way to send this through the AJAX data setting? A MIRACLE posted:Also use HAML, stop using ERB That ship has sailed for this app.
|
# ¿ Nov 6, 2014 22:59 |
|
The Milkman posted:Yeah, Eloquent Ruby, POODR, and The RSpec Book are the three must have books. You're unlikely to grasp the majority of it the first time through but the more you expose yourself to the concepts as you work the more you'll absorb and improve. I'm sure this is heresy or something, but is RSpec really that much better than the built in testing suite? I found a quick introduction to it in one of the books I read (Eloquent Ruby, maybe?), very poor documentation and examples online, and I just didn't see how it was fundamentally better than the unit tests and fixtures. Are there tests I can do in RSpec that I can't do with the built-in testing framework, or is it just supposed to be more slick and fashionable? I'll admit that I find it tiresome that every Rails tool I use has something newer/shinier/better that everyone says I should be using instead (except when I shouldn't) - Pry instead of the built-in debugger, HAML instead of erb, RSpec instead of whatever the built-in tools are called, and so on. I'd rather get proficient at using a set of good tools, than constantly be in learning curves for things that are only marginally better, and possibly not as stable. As an example, we recently updated our Ruby and Rails versions, which made the built-in debugger almost useless. So, we're using Pry now, but I get some weird behavior from it sometimes, as well as some memory errors in my testing. I don't know if Pry isn't quite ready for prime time, or I just don't know how to use it correctly. I also don't know if Pry is causing the memory errors, or if something in my code changes is doing that. So, everything slows down and gets harder just because we want to recapture the same functionality we had before upgrading. Sorry, I'll quit ranting now. Peristalsis fucked around with this message at 16:51 on Nov 21, 2014 |
# ¿ Nov 21, 2014 16:47 |
|
xenilk posted:Yeah I've been working on a project to harden my rails skills but I just like reading on it from time to time I enjoyed Eloquent Ruby pretty well. I also liked Design Patterns In Ruby. It's more specialized, but there's still some good, generally useful stuff in there, in addition to the pattern-specific parts. Arachnamus posted:With any of these things nobody who isn't a complete tool will think less of you for using one over the other, be that rspec vs testunit, erb vs haml, etc etc. Use what works for you and your team. Somewhere deep within the bowels of my mind, I knew this. I guess I was just blowing off some steam. Peristalsis fucked around with this message at 21:30 on Nov 21, 2014 |
# ¿ Nov 21, 2014 21:20 |
|
Here's a quick question. I have an object foo of type Bar with a string property called prop. I execute the following: code:
original replacement original If I instead execute this: code:
original replacement replacement So, it appears that using sub! with an object property changes the property, but the change doesn't save, whereas setting it as an explicit assignment does. Does anyone know if this is intended behavior, or if there must just be some other, subtle problem in my code making it do this?
|
# ¿ Dec 12, 2014 17:24 |
|
Smol posted:Model attributes that are not marked as serializable (stuff that is saved as json or yaml strings in the database, usually arrays) are only saved when they are marked to be dirty, i.e. when you use the setter methods. If you mutate the values directly, Rails doesn't know about that. necrotic posted:While I wouldn't recommend it for this use case, you can force an attribute to dirty by calling foo.prop_will_change!. See the API Docs for more on dirty attributes. Awesome, thanks folks! I don't mind going through the setter, I just wanted to understand what's going on.
|
# ¿ Dec 12, 2014 19:08 |
|
I have a file organization question. I'm writing a data import facility for our RoR application. I want to allow for the possibility of other importers in the future, so I extracted what core code I could into a mixin module, put that module in the lib directory, included it in the new importer class, and I put that new class in app/models/importers. Rails Console can instantiate the new objects, but when I try to write unit tests, they fail, because the rake testing function won't recognize the constant "Imports". Note that this class is NOT tied to any data table, but app/models seemed like the logical place to put it (please correct me if there's a better place for this entirely). We have some other code that does something similar, but uses subclasses of a class in the root model directory, instead of a standalone class with a mixin. Do I have to move my importer class file up into the models directory? I really like having the files organized this way, since I anticipate having a couple of more of these import classes, and I don't really want them to clutter up a main code directory with pretty similar functionality. But if I'm breaking Rails's brain, I don't want to have to fight it constantly just for the sake of my directory being pretty. Am I missing anything obvious that would resolve this nicely?
|
# ¿ Jan 29, 2015 22:19 |
|
Thanks for the responses. I'm somewhere between glad and annoyed that there's not a standard answer - glad because it means I'm not just an idiot for not knowing it, and annoyed because now I have to figure out what convention is going to be "right" for this particular situation. I guess I'll try a couple of things, and hope that some layout gives us both code and tests that work, and I'll decree that that's the canonical way to do it from now on. At least my overall approach (a folder of related classes that share a mixin module) didn't elicit rage and scorn. And one of the reasons I wanted to put this in a subfolder of models was to underscore the fact that it's not ActiveRecord, just a collection of classes we use. Honestly, I kind of like the idea of giving it its own directory just under app, or maybe app/misc_classes/imports, but that would undermine the other reason I put this in app/models - namely that we already have a similar, parallel structure for another one of our sets of classes, and I don't really want to refactor the other guy's code out into my new arrangement. I think I gave the impression that the actual code doesn't work - that's not the case. The module seems to load fine and the class works with it so far - maybe 25% of the functionality is in it right now. The problem is that the unit test won't work. I'm at home so I don't have the error message handy, but I think it was some problem with recognizing "Imports" in Imports::MyImportClass. Oh, and this app is in Rails 3.something, though we did upgrade to Ruby 2.1.1, I think.
|
# ¿ Jan 30, 2015 07:29 |
|
|
# ¿ Apr 27, 2024 11:35 |
|
Pollyanna posted:Actually, that reminds me - a lot of the Rails projects I've made are just straight "models -> database schema -> CRUD ops" setups, with rarely anything much more complicated than Users and Posts. What cases are those where you would actually use non-AR backed models, modules and extensions, and other complicated stuff? In my case, we have a system that tracks file metadata, and we want to be able to import spreadsheets of metadata for new files. We need to look at the metadata file itself, loop over each row in it, and extract metadata from each row. We also need logic to track down the files on a network drive to which each row's metadata applies. The logic for parsing this metadata file is cumbersome and irrelevant to the rest of the system (at least once the files are located and described). I don't need to record anything about the parser itself to the database. Any information about an individual run of the parser could just be written to a log file, or, at worst, stored in a "parsing_results" table.* I guess I think of it like this: if I'm writing a substantial program to do something - one that just executes a task rather than being of enough intrinsic interest to put info about it in the database - then I consider making it a non-AR model (or "misc_class" or whatever). The parser above is definitely an object (model?) in the system, but nothing about it is of interest to our users, and nothing about it changes from one use to the next, except the results and possibly the configuration. Changing our importer to do a different kind of work is more aptly suited to having a different (sub-)class, than it is to having a different row about it in a database. * This could change if the parser gets more complicated, and needs to be tweaked and configured for each run. At that point, one could argue that saving the configuration and results of a parsing run would at least make for a decent audit table. Even then, though, it might make more sense to have a "parser_details" table, than to pretend that the parser is some sort of fundamental data object that relates to any other data object in the app. Edit: We also have a process that runs overnight to validate that none of the data files that our system tracks have gone missing or become corrupted. I made this a class method of our data file AR class, but it's pretty large, and may grow to check things besides data files. I probably should have made it its own, non-AR class. There aren't different instances of the validator that have different attributes that we need or want to record in a database, it's just a program that runs periodically, and sends an email and writes a note to a log if it finds any problems. Peristalsis fucked around with this message at 21:44 on Jan 30, 2015 |
# ¿ Jan 30, 2015 21:34 |