Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
necrotic
Aug 2, 2005
I owe my brother big time for this!

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? :ohdear:

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.

Adbot
ADBOT LOVES YOU

Thalagyrt
Aug 10, 2006

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).

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.

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.

Chilled Milk
Jun 22, 2003

No one here is alone,
satellites in every home

Dystram posted:

I love working with Rails but I feel like a fraud, using gems for everything.

Should I try rolling my own functionality for lots of things rather than just installing a bunch of gems if I ever want to land a Rails dev job?

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.

KoRMaK
Jul 31, 2012



What is that?

The Journey Fraternity
Nov 25, 2003



I found this on the ground!

KoRMaK posted:

What is that?

Plain Old Ruby Objects.

necrotic
Aug 2, 2005
I owe my brother big time for this!

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.

Thalagyrt
Aug 10, 2006

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.


I had not heard of Consul and will check it out. I do like the idea of scope-centric authorization.

Henning (the author) has a great talk about Consul if you want to watch it!

http://bizarre-authorization.talks.makandra.com

necrotic
Aug 2, 2005
I owe my brother big time for this!

Thalagyrt posted:

Henning (the author) has a great talk about Consul if you want to watch it!

http://bizarre-authorization.talks.makandra.com

Excellent, thanks!

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through
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.

Pollyanna
Mar 5, 2005

Milk's on them.


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.

KoRMaK
Jul 31, 2012



MasterSlowPoke posted:

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.

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.

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

MasterSlowPoke posted:

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.

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:
class PizzaAllocator
  def initialize(parent, slice_count=8)
    @parent = parent
    @slice_count = slice_count
  end

  def allocate!
    @parent.transaction do
      @parent.master_count = @slice_count
      @parent.children.each do |c|
        # do child slice allocation here
        c.save
      end
      @parent.save
    end
  end
end
If you're encoding on a specific allocation of slices to children, set up the allocator to take them as inputs between construction and allocation.

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.

Jaded Burnout
Jul 10, 2004


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.

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.

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.

Doh004
Apr 22, 2007

Mmmmm Donuts...

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.

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.

Are you familiar with MVC or MVVM design patterns?

kayakyakr
Feb 16, 2004

Kayak is true

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.

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.

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.

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through

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.

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:
snip
If you're encoding on a specific allocation of slices to children, set up the allocator to take them as inputs between construction and allocation.

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.

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:
class Parent
def update
  super
  PizzaAlloccator.allocate
end
That's similar to what I was doing before this refactoring process but it feels a little too hackish.

Pollyanna
Mar 5, 2005

Milk's on them.


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

KoRMaK
Jul 31, 2012



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.


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:
class Parent
def update
  super
  PizzaAlloccator.allocate
end
That's similar to what I was doing before this refactoring process but it feels a little too hackish.
You should be able to control this in your update controller methods. Are you using inherit resources or something that is taking care of your submitted form data?

KoRMaK
Jul 31, 2012



Pollyanna posted:

I wouldn't have spent so much time flopping around all frustrated and confused. :(
This is what programming is. Any career or craft is like that: you just gotta do it. There's no way to avoid the learning curve. You can educate yourself, but when you apply it to a practical case for the first time you're gonna stumble around for a while.

kayakyakr
Feb 16, 2004

Kayak is true

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.


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:
class Parent
def update
  super
  PizzaAlloccator.allocate
end
That's similar to what I was doing before this refactoring process but it feels a little too hackish.

Call the allocator from the controller.

Ruby code:
class ParentController
  def create
    ...
    if @parent.save
      PizzaAllocator.allocate @parent # Or if it can be asynchronous as a job: PizzaAllocatorJob.perform_later @parent
    end
  end

  def update 
    ...
    if @parent.save
      PizzaAllocator.allocate @parent
    end
  end
end

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

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.

Ruby code:
class Parent
def update
  super
  PizzaAlloccator.allocate
end
That's similar to what I was doing before this refactoring process but it feels a little too hackish.
Is the form for Parent or is it for some other concept that includes a Parent and its Children? Would a form for a Family instance that knows how to create a Parent and Children and allocate pizzas and order a beer (I'm at Kush btw) simplify things?

MasterSlowPoke
Oct 9, 2005

Our courage will pull us through
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?

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

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.

Where's the conventional place to put PizzaAllocator? In with the models?

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.

Jaded Burnout
Jul 10, 2004


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. :(

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.

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.

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.

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. :(

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.

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

Pollyanna
Mar 5, 2005

Milk's on them.


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.

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.

I'll have to check out some of those styleguides then. And I'd love to hear about your testing approach :3:

Chilled Milk
Jun 22, 2003

No one here is alone,
satellites in every home

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.

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.

Well, I'm always interested in other devs' approaches and processes.

Hughlander
May 11, 2005

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:
#!/usr/bin/env bundle install
Turns out yes you can!

code:
#!/usr/bin/env bundle install --gemfile
plus a chmod a+x makes the gemfile executable *AND* still works with the bundle command natively.

That may be one of the cooler things I've done today.

Jaded Burnout
Jul 10, 2004


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.

Chilled Milk
Jun 22, 2003

No one here is alone,
satellites in every home
I don't suppose there's a way to have basic http auth always reprompt for credentials?

necrotic
Aug 2, 2005
I owe my brother big time for this!

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.

Smol
Jun 1, 2011

Stat rosa pristina nomine, nomina nuda tenemus.
Well, you could just send a 401 every other request to each user.

EVGA Longoria
Dec 25, 2005

Let's go exploring!

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.

Jaded Burnout
Jul 10, 2004


EVGA Longoria posted:

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.

Without STI I don't think there's a Rails-y way to do this.

Pardot
Jul 25, 2001




EVGA Longoria posted:

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.

If you go the lookup table route, don't maintain it by hand, do a view with something like this

code:
***=# select * from whatever;
 id
----
  1
 34
(2 rows)

Time: 0.150 ms
***=# select * from whatever2;
 id
----
  2
 68
(2 rows)

Time: 0.113 ms
***=# select relname as tablename, w.* from whatever as w
join pg_class on w.tableoid = oid
union all
select relname as tablename, w.* from whatever2 as w
join pg_class on w.tableoid = oid
;
 tablename | id
-----------+----
 whatever  |  1
 whatever  | 34
 whatever2 |  2
 whatever2 | 68
(4 rows)

Peristalsis
Apr 5, 2004
Move along.
I have a question about using AJAX in Rails.

Here's some simplified code to illustrate my problem:

In foobars_controller.rb
code:
class FoobarController < ApplicationController
  def new
    @foobar = Foobar.new
    @other_var = 123
    ...
  end
end
In foobar's _form.html.erb
code:
<script>
  $(document).ready(function() {
    $.ajax({
      url: some.route.to.function
      data: {
        other_var: ?????
        ...
      }
    })
  });
</script>

<html>
  <% @other_var is visible here, I just need to get its value into the AJAX call, above %>
  ...
</html>
What I need to know is how to get @other_var's value into the AJAX call in _form.html.erb. I know that the html in this file has access to instance variables in the controller, but I don't know how to make them accessible to the AJAX call from there.

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.

A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

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:
{
...
  data: {
     value: $("#myInputField").val();
  }
}
If the value never changes, you can just insert it with <%= @my_var %> into javascript the same as HTML

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

kayakyakr
Feb 16, 2004

Kayak is true

A MIRACLE posted:

you mean like this? Add the jQuery library, which makes it easier to pull data from your forms

JavaScript code:
{
...
  data: {
     value: $("#myInputField").val();
  }
}
If the value never changes, you can just insert it with <%= @my_var %> into javascript the same as HTML

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.

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.

Peristalsis
Apr 5, 2004
Move along.

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.

Adbot
ADBOT LOVES YOU

A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

As an array object? JSON and rails supports arrays over AJAX

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply