|
Doh004 posted:I'm just slowly working my way through my first rails application and just rolled my own user authentication. I know there's tons of gems out there that do this already though... but it's a good learning experience, right? It is good knowledge, but after you've done it once start using Devise. Its amazingly powerful and really quick to get all of the functionality you need for authentication (including pluggable schemes, like oAuth and 2FA). Authorization is a different beast. I used to recommend CanCan, but its been discontinued (although the community has picked it up with CanCanCan). I've started using Pundit, which is basically helpers for writing authorization rules inside of POROs, and I have been loving it. It's a bit more verbose, but makes testing and understanding the system so much easier.
|
# ? Oct 15, 2014 18:00 |
|
|
# ? May 28, 2024 07:41 |
|
necrotic posted:It is good knowledge, but after you've done it once start using Devise. Its amazingly powerful and really quick to get all of the functionality you need for authentication (including pluggable schemes, like oAuth and 2FA). I honestly disagree on using Devise for everything. We've rolled our own authentication in-house and couldn't be happier. Devise didn't do what I wanted - it got me 95% of the way to where I wanted to be, then I spent more time than it took to roll my own authentication wrangling Devise to sort of kind of maybe do what I wanted. I ended up ripping almost all of devise's built in functionality out, then realized I may as well roll my own. It meets a specific, and admittedly common, use case, but if you're not in that exact use case it falls apart spectacularly. This is the case with the majority of gems that try to be a solution for everyone like that. Pundit's no exception to this one-size-fits-all problem. Pundit assumes that authorization is going to be based on roles on the user, and the second you want to bring a secondary object (user has x permissions on account y and z permissions on account q, for example) into the authorization scope, Pundit falls apart without extensive modification. The whole concept of doing authorization in functions that take two objects is kind of silly anyway. Why should you have both a function to check if a user has rights on an object as well as a scope to return only the objects the user has rights to? Simply use the scope all the time. Check out Consul for an example of that. It's far more flexible than Pundit and can handle extremely bizarre authorization requirements very elegantly.
|
# ? Oct 15, 2014 18:13 |
|
Dystram posted:I love working with Rails but I feel like a fraud, using gems for everything. No, you should be using gems where it's a good fit. But, having an idea of how it accomplishes things under the hood will expose you to common patterns and practices, as well as being able to work with that particular gem.
|
# ? Oct 15, 2014 18:16 |
|
necrotic posted:POROs
|
# ? Oct 15, 2014 18:16 |
|
KoRMaK posted:What is that? Plain Old Ruby Objects.
|
# ? Oct 15, 2014 18:27 |
|
Thalagyrt posted:I honestly disagree on using Devise for everything. We've rolled our own authentication in-house and couldn't be happier. Devise didn't do what I wanted - it got me 95% of the way to where I wanted to be, then I spent more time than it took to roll my own authentication wrangling Devise to sort of kind of maybe do what I wanted. I ended up ripping almost all of devise's built in functionality out, then realized I may as well roll my own. It meets a specific, and admittedly common, use case, but if you're not in that exact use case it falls apart spectacularly. This is the case with the majority of gems that try to be a solution for everyone like that. This is true for any language and any set of 3rd party libraries: they work for the most common cases, but once you need something specialized (I would be interested in what use case you had that didn't fit) rolling your own is generally the best approach. quote:Pundit's no exception to this one-size-fits-all problem. Pundit assumes that authorization is going to be based on roles on the user, and the second you want to bring a secondary object (user has x permissions on account y and z permissions on account q, for example) into the authorization scope, Pundit falls apart without extensive modification. The whole concept of doing authorization in functions that take two objects is kind of silly anyway. Why should you have both a function to check if a user has rights on an object as well as a scope to return only the objects the user has rights to? Simply use the scope all the time. Check out Consul for an example of that. It's far more flexible than Pundit and can handle extremely bizarre authorization requirements very elegantly. I had not heard of Consul and will check it out. I do like the idea of scope-centric authorization.
|
# ? Oct 15, 2014 19:27 |
|
necrotic posted:This is true for any language and any set of 3rd party libraries: they work for the most common cases, but once you need something specialized (I would be interested in what use case you had that didn't fit) rolling your own is generally the best approach. Henning (the author) has a great talk about Consul if you want to watch it! http://bizarre-authorization.talks.makandra.com
|
# ? Oct 15, 2014 19:49 |
|
Thalagyrt posted:Henning (the author) has a great talk about Consul if you want to watch it! Excellent, thanks!
|
# ? Oct 15, 2014 20:01 |
|
I'm having a little trouble finding the best way to handle my associations and callbacks. I have a Parent and a Child class. Parent has a field called master_count, Child has a count field. Each child of the parent needs to be assigned a portion of the master_count. Ex. Parent has a master_count of 10 ChildA gets a count of 6 ChildB gets a count of 4 If a child is created/updated, the parent needs to recalculate which children get which slices of the pie. They're currently all in a nested attribute form. Ideally, I would like all of the Children to be updated and then Parent calls it's assign_count method. However, it looks like Parent's after_save callbacks run before the Children get saved, so I can't call assign_counts there. I thought about giving Child's association a touch: true, but that will cause an infinite loop. I feel like I'm missing something simple.
|
# ? Oct 22, 2014 13:52 |
|
How do I know what the right architecture of an application should be? Right now, I have a Controller that submits a search form's parameters to a non-AR Search object, which instantiates an API Client that submits a request using those parameters, the results of which get sent to the Search object and processed, and the end result is sent back to the Controller for display. What is this sort of program organization called? Architecture? How do I know that this is the right/best way to do it? It being making a Search object and an API Client object to handle my searches. Is there a way to predict how this will end up looking, so I don't have to constantly refactor? Also, in making my most recent application, I'm realizing that I really need to learn to do Controller testing/outside-in development. That would have made things a lot easier for me.
|
# ? Oct 22, 2014 13:56 |
|
MasterSlowPoke posted:I'm having a little trouble finding the best way to handle my associations and callbacks. What order are these things getting saved as? Why are you saving the parent first instead of the children? I'd put the after_save on the children to call the Parent.
|
# ? Oct 22, 2014 14:15 |
|
MasterSlowPoke posted:I'm having a little trouble finding the best way to handle my associations and callbacks. In a situation like this, I'd be really tempted to move the behavior of what you're actually working with out to a new class, even if it isn't something actually persisted into the database. If you're dealing with how to allocate a pizza, I'd make a PizzaAllocator class that takes a parent, and a count of how many slices of pizza you're splitting up. The PizzaAllocator would update the master_count on the Parent, and the count on the Child instances, and wrap it all in a transaction so it rolls back if it fails partway through: Ruby code:
Callbacks and associations get confusing really quickly, and I've found that moving that logic out to its own class can salvage a bad situation.
|
# ? Oct 22, 2014 14:22 |
|
Pollyanna posted:How do I know what the right architecture of an application should be? Right now, I have a Controller that submits a search form's parameters to a non-AR Search object, which instantiates an API Client that submits a request using those parameters, the results of which get sent to the Search object and processed, and the end result is sent back to the Controller for display. Your `Search` object is just a model. Doesn't have to be ActiveRecord to be a model. A model is a conceptual thing. If it helps, think of the API client as the same as a mysql client; it's just an adapter to a service. Your model is wrapping that service to present the data to the rest of the application in line with your specific domain. If you'd like a simple example of an app that talks to several services you can try this one: https://github.com/alphagov/collections-api It uses request specs instead of cucumber (because it's an API) but they serve the same purpose. That app was written outside-in, as always.
|
# ? Oct 22, 2014 14:28 |
|
Pollyanna posted:How do I know what the right architecture of an application should be? Right now, I have a Controller that submits a search form's parameters to a non-AR Search object, which instantiates an API Client that submits a request using those parameters, the results of which get sent to the Search object and processed, and the end result is sent back to the Controller for display. Are you familiar with MVC or MVVM design patterns?
|
# ? Oct 22, 2014 14:29 |
|
Pollyanna posted:How do I know what the right architecture of an application should be? Right now, I have a Controller that submits a search form's parameters to a non-AR Search object, which instantiates an API Client that submits a request using those parameters, the results of which get sent to the Search object and processed, and the end result is sent back to the Controller for display. That pattern sometimes goes as the "Service" pattern and is a very standard way to break out of the standard rails MVC. In essence, you're adding a 4th layer to move complex logic out of the controller. Though I have to ask, what is wrong with constantly refactoring? That's how a project goes in my mind: You do it, get it done, figure out a better way, do it better, and so on. Just make sure what you're doing works at every step and you're good to go. Cocoa Crispies posted:In a situation like this, I'd be really tempted to move the behavior of what you're actually working with out to a new class, even if it isn't something actually persisted into the database. This is how I'd do it as well. If it's an essential task (ie it's bad if the allocation is ever inaccurate), then use the allocator class to handle all of the save of parent and child records. That way, if anything at all goes wrong, you've got your transaction to fall back on. If it's nonessential, split out the allocation as in the example, and put it into an async job triggered from the controller.
|
# ? Oct 22, 2014 15:13 |
|
Cocoa Crispies posted:In a situation like this, I'd be really tempted to move the behavior of what you're actually working with out to a new class, even if it isn't something actually persisted into the database. This makes sense. The allocation code is cluttering up Parent, and it'll be much easier to test and modify outside on its own. KoRMaK posted:What order are these things getting saved as? Why are you saving the parent first instead of the children? I'd put the after_save on the children to call the Parent. I'm using a form for the parent, which has nested fields for each of the children. Rails processes and saves the parent before it even looks at the children, which makes sense for most cases. Ideally I'd be able to process all the data on the forms for the Children and the Parent, save them, and then call the PizzaAllocator, which will process the data and save them again. I'm just not sure how to make this happen. My main problem now is that I don't know where to put the calls to PizzaAllocator. I've learned that I can use update_column instead of save in the Allocator in order to avoid triggering after_save callbacks. I can put my calls to the Allocator in after_saves on the parent and the children, but that's not ideal. A parent with three kids is going to get allocated up to 4 times, and only the last one actually matters. Is there a way to wrap all the update code into a packet and then execute the Allocation code? I suppose I could do something like: Ruby code:
|
# ? Oct 22, 2014 16:35 |
|
I don't mind refactoring, I just wish I knew about these kindsa patterns and how to do Cucumber/RSpec testing better so that I wouldn't have spent so much time flopping around all frustrated and confused. My most recent application kind of became a hellbeast when I tried to add on functionality and validations and exception rescuing and all that...I ended up heavily tying the Search object to the Yelp API, because getting the information I wanted from it was proving to be a huge pain in the rear end- and it needed a lot of processing. It was only last night that I figured out that I needed to make Search completely unaware of what the backend API was. I think my goals after this project are to review how to test Models, Controllers, and Views, and just Rails testing in general - it seriously saved my rear end this time. I also need to learn patterns like that Service pattern as well. Also learn how to write things like user stories and specifications, cause that would have made my goals a lot clearer. Pollyanna fucked around with this message at 16:48 on Oct 22, 2014 |
# ? Oct 22, 2014 16:45 |
|
MasterSlowPoke posted:This makes sense. The allocation code is cluttering up Parent, and it'll be much easier to test and modify outside on its own.
|
# ? Oct 22, 2014 16:54 |
|
Pollyanna posted:I wouldn't have spent so much time flopping around all frustrated and confused.
|
# ? Oct 22, 2014 16:56 |
|
MasterSlowPoke posted:This makes sense. The allocation code is cluttering up Parent, and it'll be much easier to test and modify outside on its own. Call the allocator from the controller. Ruby code:
|
# ? Oct 22, 2014 17:05 |
|
MasterSlowPoke posted:This makes sense. The allocation code is cluttering up Parent, and it'll be much easier to test and modify outside on its own.
|
# ? Oct 22, 2014 17:15 |
|
Makes sense. I've just been read to keep as much out of the controller as possible I'm wary of doing anything there. Makes sense that it's something the controller should do over anything else. Where's the conventional place to put PizzaAllocator? In with the models?
|
# ? Oct 22, 2014 17:16 |
|
MasterSlowPoke posted:Makes sense. I've just been read to keep as much out of the controller as possible I'm wary of doing anything there. Makes sense that it's something the controller should do over anything else. I'd put a PizzaAllocator or a non-persisted Family class in the models directory. They're models, even if you don't need to keep them in the database.
|
# ? Oct 22, 2014 17:20 |
|
Pollyanna posted:I don't mind refactoring, I just wish I knew about these kindsa patterns and how to do Cucumber/RSpec testing better so that I wouldn't have spent so much time flopping around all frustrated and confused. There's lots of styleguides out there you can use as a basis until you get the hang of it. That applies to user stories too. Also don't forget that Rails is arranged in a very opinionated way and that extends to testing, too. Not everyone agrees with its defaults. Most everyone agrees that more testing is better than less testing, and lots of people think TDD and BDD are good approaches. Beyond that it's a lot of nuance. Would there be any value to me writing up the approach that I (and others) take with regard to Rails testing? There's no definitive approach but I find this one effective.
|
# ? Oct 22, 2014 18:19 |
|
Pollyanna posted:I don't mind refactoring, I just wish I knew about these kindsa patterns and how to do Cucumber/RSpec testing better so that I wouldn't have spent so much time flopping around all frustrated and confused. You can't learn how to architect software just buy reading books or blogs. Like generally in life, you need to make lots of mistakes on your own to really learn. So don't worry too much - just keep doing it and you'll eventually get your own vision how to do it properly. Smol fucked around with this message at 18:35 on Oct 22, 2014 |
# ? Oct 22, 2014 18:31 |
|
Arachnamus posted:There's lots of styleguides out there you can use as a basis until you get the hang of it. That applies to user stories too. I'll have to check out some of those styleguides then. And I'd love to hear about your testing approach
|
# ? Oct 22, 2014 20:55 |
|
Arachnamus posted:There's lots of styleguides out there you can use as a basis until you get the hang of it. That applies to user stories too. Well, I'm always interested in other devs' approaches and processes.
|
# ? Oct 22, 2014 23:12 |
|
Ok, I was going to ask this as a question but instead I just tried it and it worked and it was awesome... Oddish question, can I have a Gemfile that is also an executable script with a shebang? Some tools at work have an automated update system. Each time it runs it looks for a git tag and updates itself. Each time a different set of tools run they update themselves. One set of tools watches the installers of the other and if the SHA of the file is different than the last time it runs, it runs the installer again. We just updated from 1.8.7 and part of that I rolled out a project wide Gemfile. The same day already found a case where I have to bump a version of a gem in the Gemfile, and would like to tie into these update scripts. The easiest thing would be if I can just mark the gemfile itself as one of these installers with something like: code:
code:
That may be one of the cooler things I've done today.
|
# ? Oct 23, 2014 16:07 |
|
Hughlander posted:plus a chmod a+x makes the gemfile executable *AND* still works with the bundle command natively. You are a strange person and I like it.
|
# ? Oct 23, 2014 20:00 |
|
I don't suppose there's a way to have basic http auth always reprompt for credentials?
|
# ? Oct 29, 2014 02:29 |
|
The Milkman posted:I don't suppose there's a way to have basic http auth always reprompt for credentials? Not a built-in way. You can hack it by redirecting them to a URL with a bogus username, but its not very friendly.
|
# ? Oct 29, 2014 03:33 |
|
Well, you could just send a 401 every other request to each user.
|
# ? Oct 30, 2014 09:43 |
|
Any suggestions for searching one field across multiple models to find a result? Specifically, I have a UUID field in 2 models and I want to search both when I get sent a UUID. I could make an external lookup table (which I might end up doing), or I could make a view to render both. Wondering if there's a rails-centric way to do this.
|
# ? Nov 6, 2014 17:17 |
|
EVGA Longoria posted:Any suggestions for searching one field across multiple models to find a result? Without STI I don't think there's a Rails-y way to do this.
|
# ? Nov 6, 2014 17:19 |
|
EVGA Longoria posted:Any suggestions for searching one field across multiple models to find a result? If you go the lookup table route, don't maintain it by hand, do a view with something like this code:
|
# ? Nov 6, 2014 17:37 |
|
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 |
Peristalsis posted:I have a question about using AJAX in Rails. you mean like this? Add the jQuery library, which makes it easier to pull data from your forms JavaScript code:
Also use HAML, stop using ERB I'm pretty good at Rails controllers with AJAX so just hit me up if you have more q's. A MIRACLE fucked around with this message at 22:45 on Nov 6, 2014 |
|
# ? Nov 6, 2014 22:41 |
|
A MIRACLE posted:you mean like this? Add the jQuery library, which makes it easier to pull data from your forms meh, ERB is fine. As to the AJAX thing, you could embed @other_var into a hidden input and then pull it by ID. You could also embed it directly into a script tag at the end of your document. If you go that route, I'd embed it either as a global that your JS will pick up (in jquery's onready, don't forget the jquery-turbolinks gem as well if you're using turbolinks), or as an initialization variable to kick off the execution of your JS.
|
# ? Nov 6, 2014 22:53 |
|
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 |
|
|
# ? May 28, 2024 07:41 |
As an array object? JSON and rails supports arrays over AJAX
|
|
# ? Nov 6, 2014 23:12 |