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
xtal
Jan 9, 2011

by Fluffdaddy
Conditional unique validations are going to be subject to race conditions unless you move the condition logic to the database, which would get messy.

Adbot
ADBOT LOVES YOU

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
Thank you! That all seems reasonable, and I also just realised that I'm trying to fit a square peg into a round hole. If it's critical that I make this uniqueness check, I should just create a new table with a foreign key on user_id and city_id to track the active city and then just give that a unique index. I should have thought of that as soon as my first attempt failed consistently, I just got tunnel vision because I was seeing examples of validates_uniqueness_of that very closely matched what I wanted, and wasn't sure why I couldn't get it to work.

e: or, even simpler, just have "active city" be either null or a foreign key (to city id) in the user table. i was definitely approaching this arse backwards

Sulla Faex fucked around with this message at 09:59 on Jun 10, 2020

Steely Dad
Jul 29, 2006



I'm working on a Rails app as a solo project. My project is essentially a ticket-tracking system aimed at small teams (not exactly, but it's a close analogy). I'm a pretty experienced back-end developer; I've been using Rails off and on since 2005, and before that I worked with Perl and PHP. I've got a working knowledge of the front end, but it's definitely not my wheelhouse.

Given that I'm working alone and not that big a fan of JS, I'm inclined to build a more traditional erb-based app returning HTML, rather than a JSON API with a separate React/Angular/Vue app consuming it. It just seems like a lot of additional complexity for a single-person project. So I'm looking around for JS frameworks to add behavior to DOM elements where needed, rather than build a whole client app.

The two options I've been considering are Stimulus and Alpine. Stimulus has the Basecamp imprimatur, but doesn't seem to have gotten much adoption and the repo is getting stale. Alpine's under more active development, and has a more interesting story, but I'm leery of picking some random JS library that dies out after six months and then I've got to rewrite a bunch of my front end. Anyone here have any experience or feedback on these, or on alternatives?

xtal
Jan 9, 2011

by Fluffdaddy
I haven't used any of those but have also heard about htmx.org a lot lately

Steely Dad
Jul 29, 2006



xtal posted:

I haven't used any of those but have also heard about htmx.org a lot lately

Thanks, that's exactly the sort of thing I'm interested in. I'll check it out.

enki42
Jun 11, 2001
#ATMLIVESMATTER

Put this Nazi-lover on ignore immediately!
FWIW, I use Vue in an app that's 100% progressive enhancement (everything works 100% without JS but we augment certain things), and it works pretty well. Occasionally you'll run into some awkwardness needing to duplicate things in ERB and Vue, but it's more rare than you think.

Steely Dad
Jul 29, 2006



Interesting. Have you tried Alpine before? It's modeled after Vue, and it's designed to do what you're using Vue to do. My hope is to keep payloads as small as possible.

enki42
Jun 11, 2001
#ATMLIVESMATTER

Put this Nazi-lover on ignore immediately!
Alpine looks pretty cool, I'm going to check that out.

So far, bundle size hasn't been a big concern. I should stress our JS usage is pretty minimal (we use it for things like adding typeahead searches, modals, better file upload components, etc.), but we're only at about 86KB gzipped (our CSS is currently a much larger concern).

duck monster
Dec 15, 2004

xtal posted:

I haven't used any of those but have also heard about htmx.org a lot lately

Oh this thing is nice. Perfect. I detest JS, it just pisses me off with its build chains and constantly moving targets and lovely SPAs with no sense of semantic properness or backward compatibility. Sure I can build React SPAs in my sleep, but I just hate it. Its such a step backwards for the industry.

This, this is nice.

Peristalsis
Apr 5, 2004
Move along.
I must be doing something very stupid here, but I can't get a method to take the right number of parameters.

I'm trying to do this:
code:
<%= bootstrap_form_tag url: new_route_for_this_ticket, layout: :horizontal do |f| %>
  <div class='container-fluid'>
    <div class='row'>
      <div class='col-sm-6'>
        <%= f.number_field(:num_new_things, 1, step: 1, min: 1) %>    # <----- The problem line
      </div>
    </div>
  </div>
<% end %>
According to the rails documentation, the number_field method of the form object takes the same parameters as the number_field_tag helper method:

rubydoc posted:

#number_field_tag(name, value = nil, options = {}) ⇒ Object

However, when I try to pass in name, value, and an options hash, I get:

code:
wrong number of arguments (given 3, expected 1..2)
Am I having a mental break, or is the documentation just wrong here? It works fine if I omit the value parameter, but then I can't set a default, which would be nice to do. Explicitly putting brackets around the options hash doesn't make a difference.

I'm using Rails version 5.2.4.3.


Edit:
Okay, technically the rails docs don't say the helper method takes the same params as number_field_tag helper method, it says it takes the same options. The method signature for the form helper method is this:

quote:

number_field(object_name, method, options = {}) public

That still looks like three params to me, and I have no idea what the "method" param is supposed to be.

Could there be a difference between the form objects returned by form_tag and form_for?

Peristalsis fucked around with this message at 21:07 on Aug 28, 2020

Tea Bone
Feb 18, 2011

I'm going for gasps.

Peristalsis posted:

I must be doing something very stupid here, but I can't get a method to take the right number of parameters.

I'm trying to do this:
code:
<%= bootstrap_form_tag url: new_route_for_this_ticket, layout: :horizontal do |f| %>
  <div class='container-fluid'>
    <div class='row'>
      <div class='col-sm-6'>
        <%= f.number_field(:num_new_things, 1, step: 1, min: 1) %>    # <----- The problem line
      </div>
    </div>
  </div>
<% end %>
According to the rails documentation, the number_field method of the form object takes the same parameters as the number_field_tag helper method:


However, when I try to pass in name, value, and an options hash, I get:

code:
wrong number of arguments (given 3, expected 1..2)
Am I having a mental break, or is the documentation just wrong here? It works fine if I omit the value parameter, but then I can't set a default, which would be nice to do. Explicitly putting brackets around the options hash doesn't make a difference.

I'm using Rails version 5.2.4.3.


Edit:
Okay, technically the rails docs don't say the helper method takes the same params as number_field_tag helper method, it says it takes the same options. The method signature for the form helper method is this:


That still looks like three params to me, and I have no idea what the "method" param is supposed to be.

Could there be a difference between the form objects returned by form_tag and form_for?

The boot strap form gem redefines most of the helpers and they don't always work 1:1. I've come against this before. If you can look into the source code for the gem, but from the top of my head I think you might need to pass the value as a named parameter. Try value:123 or default:123

Peristalsis
Apr 5, 2004
Move along.

Tea Bone posted:

The boot strap form gem redefines most of the helpers and they don't always work 1:1. I've come against this before. If you can look into the source code for the gem, but from the top of my head I think you might need to pass the value as a named parameter. Try value:123 or default:123

Thanks for your response. Neither value nor default worked, but I think I'm going to just omit the default value for now, so I can move on and get some work done. If I get some time, I might look into the underlying code, but I'm not sure I'm willing to do that. I've always had trouble with the helper methods (even without bootstrap, if I recall correctly), and I'm not sure I want to take on any additional frustration or delays right now.

Tea Bone
Feb 18, 2011

I'm going for gasps.

Peristalsis posted:

Thanks for your response. Neither value nor default worked, but I think I'm going to just omit the default value for now, so I can move on and get some work done. If I get some time, I might look into the underlying code, but I'm not sure I'm willing to do that. I've always had trouble with the helper methods (even without bootstrap, if I recall correctly), and I'm not sure I want to take on any additional frustration or delays right now.

No worries, but that's strange
code:
<%= f.number_field(:num_new_things, value:1, step: 1, min: 1) %>
is working fine for me? Any arbitrary options should just get passed as HTML attributes. Unless you have any other gems or monkey patches interfering with the :value option it should work.
if you throw another gibberish param in there (say foo:'bar') then inspect the HTML of the rendered element does foo show up as an attribute?

i.e:
code:
<%= f.number_field(:num_new_things, step: 1, min: 1, foo:'bar') %>
should render as
code:
<input  step="1" min="1" foo="bar" name="num_new_things" id="num_new_things" class="form-control" type="number">

xtal
Jan 9, 2011

by Fluffdaddy
Put a debugger before the line in question and poke around the source_location, arguments etc

Peristalsis
Apr 5, 2004
Move along.

Tea Bone posted:

No worries, but that's strange
code:
<%= f.number_field(:num_new_things, value:1, step: 1, min: 1) %>
is working fine for me? Any arbitrary options should just get passed as HTML attributes. Unless you have any other gems or monkey patches interfering with the :value option it should work.
if you throw another gibberish param in there (say foo:'bar') then inspect the HTML of the rendered element does foo show up as an attribute?

i.e:
code:
<%= f.number_field(:num_new_things, step: 1, min: 1, foo:'bar') %>
should render as
code:
<input  step="1" min="1" foo="bar" name="num_new_things" id="num_new_things" class="form-control" type="number">

Well, now it works (and foo="bar" is in there, too). I looked at another place in our codebase that used the value parameter, and which also wasn't populating the UI with it, and that seems to be working now, too. I think I'm going to call it a week, see if it's still bothering me on Monday. Thanks for your help!

enki42
Jun 11, 2001
#ATMLIVESMATTER

Put this Nazi-lover on ignore immediately!
I don't think that's bootstrap, that's standard for all the _tag vs form instance methods - the value is by default derived from the form's object and so you never pass it in (although you can override it with a value option).

Think of it this way - if that method had 3 arguments, you'd have to unnecessarily pass the value every time, when 95% of the time you just want to use the current value of whatever your model is.

To be honest, I'd consider reworking your form a bit anyway so that the controller initializes a model (without saving it), and build the form off that. That way you can specify your default values in your controller (or even your model or your DB if it's a universal default), which is going to be less buried when you come back to it, can be tested if you needed to for some reason, and you can share the same form for editing and creating if you need to do both.

Peristalsis
Apr 5, 2004
Move along.

enki42 posted:

I don't think that's bootstrap, that's standard for all the _tag vs form instance methods - the value is by default derived from the form's object and so you never pass it in (although you can override it with a value option).

Are you talking about the number of parameters it accepts/requires here? It still seems bad to me to document the signature as taking 3 params, but only accepting 2. Or am I looking at the wrong documentation?

enki42 posted:

Think of it this way - if that method had 3 arguments, you'd have to unnecessarily pass the value every time, when 95% of the time you just want to use the current value of whatever your model is.

I'm not saying that it should or shouldn't take 3 arguments, just that the documentation should match the behavior

enki42 posted:

To be honest, I'd consider reworking your form a bit anyway so that the controller initializes a model (without saving it), and build the form off that. That way you can specify your default values in your controller (or even your model or your DB if it's a universal default), which is going to be less buried when you come back to it, can be tested if you needed to for some reason, and you can share the same form for editing and creating if you need to do both.

This is a form that is collecting metadata to use to create multiple objects. It takes in a base name and the number of objects desired, and creates them. So, you pass in "My Object", and 3, and when you click submit, the system creates 3 objects, named My Object 1, My Object 2, and My Object 3. So, there is no single model to initialize in the controller before calling the form. I'm certainly open to better ideas, but using form_tag seemed the easiest way to make a form to collect data that isn't directly related to a single model.

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.

how are the models related?

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

Peristalsis posted:

Are you talking about the number of parameters it accepts/requires here? It still seems bad to me to document the signature as taking 3 params, but only accepting 2. Or am I looking at the wrong documentation?

The docs you linked are for the bare number_field_tag, not the form helper version. The form helper version automatically defaults to calling (essentially) model.__send__(:field_name) to get the default value (the second param in the one you linked).

enki42
Jun 11, 2001
#ATMLIVESMATTER

Put this Nazi-lover on ignore immediately!

Peristalsis posted:

This is a form that is collecting metadata to use to create multiple objects. It takes in a base name and the number of objects desired, and creates them. So, you pass in "My Object", and 3, and when you click submit, the system creates 3 objects, named My Object 1, My Object 2, and My Object 3. So, there is no single model to initialize in the controller before calling the form. I'm certainly open to better ideas, but using form_tag seemed the easiest way to make a form to collect data that isn't directly related to a single model.

Yeah, for situations like that that can be a good approach. If things got complicated, you could consider making a form object by including ActiveModel::Model on a new class and building the form around that. (ActiveModel::Model is basically the model stuff without any ActiveRecord logic, so you'd make a new model that represents that metadata and do the saving of the various objects inside the save of that model).

Peristalsis
Apr 5, 2004
Move along.

necrotic posted:

The docs you linked are for the bare number_field_tag, not the form helper version. The form helper version automatically defaults to calling (essentially) model.__send__(:field_name) to get the default value (the second param in the one you linked).

Sorry, I updated my original post with this link.

That still looks like 3 params to me, and there's no explanation of any of them, except to say that the options are the same as number_field_tag's options.

Jaded Burnout
Jul 10, 2004


Peristalsis posted:

Sorry, I updated my original post with this link.

That still looks like 3 params to me, and there's no explanation of any of them, except to say that the options are the same as number_field_tag's options.

mm yes so, "no explanation of any of them" aside (that's a chronic core ruby/rails docs issue), there's THREE methods (at least) for number fields.

1. number_field_tag, which is a helper, and generates some HTML for the field with no interaction with models.
2. number_field, which is a helper, and builds a Rails-y activemodel-y field but without using the actual model itself, hence you need to pass in the object name so it can name the field correctly.
3. number_field, which is a method on the form builder, and is what you're using when you call `f.number_field`, as `f` is an instance of that form builder (if it's not been overridden). The reason it takes 1..2 args instead of 3 is that it already has some knowledge about the model you're building fields for, since you gave one to the `form_for`, so it doesn't need you to tell it again.

The difference between the use of positional args vs keyword args vs some combination is due to the differing ages of the methods.

Short version: you're looking at the documentation for a similar method with the same name but on a different class.

Jaded Burnout fucked around with this message at 15:24 on Sep 14, 2020

barkbell
Apr 14, 2006

woof
Tech lead brought me in on a side project app for secure log sharing. It's a rails app and I've never done it before. Java/Angular is my day job and I do my own side projects in node/react. This erb stuff looks like php.

I've got the official documentation but are there any other really good learning resources? Also what are the good VS Code extensions or is there a certain editor that's really popular?

Jaded Burnout
Jul 10, 2004


barkbell posted:

I've got the official documentation but are there any other really good learning resources? Also what are the good VS Code extensions or is there a certain editor that's really popular?

Honestly guides.rubyonrails.org and api.rubyonrails.org will get you a long way. I don't know much about VS Code but I believe some folks do use it. Atom and Sublime Text are the big ones otherwise. There's not much of an IDE culture with Ruby, it's mostly just text editors with convenience plugins.

enki42
Jun 11, 2001
#ATMLIVESMATTER

Put this Nazi-lover on ignore immediately!

barkbell posted:

Tech lead brought me in on a side project app for secure log sharing. It's a rails app and I've never done it before. Java/Angular is my day job and I do my own side projects in node/react. This erb stuff looks like php.

I've got the official documentation but are there any other really good learning resources? Also what are the good VS Code extensions or is there a certain editor that's really popular?

If you can invest the time, going through Michael Hartl's tutorial (https://www.railstutorial.org/) is pretty comprehensive and will take you far enough to confidently navigate any Rails project.

Sivart13
May 18, 2003
I have neglected to come up with a clever title

Jaded Burnout posted:

There's not much of an IDE culture with Ruby, it's mostly just text editors with convenience plugins.
That probably depends on who you work with, I and most of my coworkers have used RubyMine for many years. If you can stomach paying money for software it has a lot of features that are really helpful.

Jaded Burnout
Jul 10, 2004


Sivart13 posted:

That probably depends on who you work with, I and most of my coworkers have used RubyMine for many years. If you can stomach paying money for software it has a lot of features that are really helpful.

Fair call.

kayakyakr
Feb 16, 2004

Kayak is true
Rubymine is a good all-in-one IDE. Personally, I use vscode and separate terminals.

Peristalsis
Apr 5, 2004
Move along.

Jaded Burnout posted:

Short version: you're looking at the documentation for a similar method with the same name but on a different class.

Thanks so much. This has been a long source of frustration for me, and I probably just never realized I was looking at the documentation for the wrong method(s).

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.

is anyone here good at searchkick

Tea Bone
Feb 18, 2011

I'm going for gasps.
I have a bug which is really stumping me.

I have a model similar to this:

code:
class Design < ApplicationRecord
	#attributes first_color, second_color, third_color
	after_create :generate_preview

	alias_attribute :foreground_1, :first_color
	alias_attribute :foreground_2, :second_color
	alias_attribute :background, :third_color


	def generate_preview
		#code to generate an image based on the colors
		self.save
	end
end
It's really that simple and there isn't much else going on in the model. The attributes first_color, second_color and third_color are all strings and are saved as a hex value including the hash. The alias attributes are simply because the colors submitted from the front end have different names.

The issue is coming with the after_create method. first and third color are saving absolutely fine. second_color however loses the hash (i.e it goes from '#000000' to '000000'). I've removed all the code to generate the image so the generate_preview method is exactly as above, does nothing but save so I know the issue isn't coming from generating the preview. If I drop the after_create method all together it saves fine.

edit. I've also removed all the alias_attributes and tried creating an instance directly from a console session and the problem persists.

Tea Bone fucked around with this message at 17:31 on Dec 18, 2020

Jaded Burnout
Jul 10, 2004


The issue is likely in `#code to generate an image based on the colors`, then. Any chance it's modifying the string in place?

Tea Bone
Feb 18, 2011

I'm going for gasps.

Jaded Burnout posted:

The issue is likely in `#code to generate an image based on the colors`, then. Any chance it's modifying the string in place?

Ah no, I had already completely removed `#code to generate an image based on the colors`. But the magic of asking the forums then solving it myself worked out. One of it's relations was calling gsub!('#','') on it. Thanks anyway!

Peristalsis
Apr 5, 2004
Move along.
I've moved a couple of partials to be rendered asynchronously with the render_async gem. They were slow loading tabs on a show page, and moving them broke tests, because (I think) the tests don't know to wait for the asynchronous tabs to finish loading. I'd like a way to continue testing these tabs. I found that RSpec/capybara is supposed to be able to render partials, but when I try that in feature tests, render is not a recognized method name. This app doesn't have dedicated controller tests, which is where I assume this is actually supposed to go, and I don't know if those allow standard UI expectations anyway. Does anyone have any suggestions for a good way to test this?

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've moved a couple of partials to be rendered asynchronously with the render_async gem. They were slow loading tabs on a show page, and moving them broke tests, because (I think) the tests don't know to wait for the asynchronous tabs to finish loading. I'd like a way to continue testing these tabs. I found that RSpec/capybara is supposed to be able to render partials, but when I try that in feature tests, render is not a recognized method name. This app doesn't have dedicated controller tests, which is where I assume this is actually supposed to go, and I don't know if those allow standard UI expectations anyway. Does anyone have any suggestions for a good way to test this?

post your test? is it a controller type test?

Peristalsis
Apr 5, 2004
Move along.

A MIRACLE posted:

post your test? is it a controller type test?

It's a very convoluted feature test - I'm replacing one of the helper methods it uses with a new method just to render and check the partial:

code:
def check_for_controls_on_publication_partial(can_edit, can_delete, can_create)
  render partial: 'myDir/myPartial', locals: {...}
end
This raises undefined method `render'.

I also tried moving the render command into the test file itself (instead of a helper), and got the same error there. Like I said, I assume render only works in controller tests, but there are no dedicated controller tests in this app. I can add one to see if it works, but I wondered if there's another best practice way to approach this, preferably keeping it in a Capybara feature test. With all the JavaScript and asynchronous stuff being done these days, others must have had (and solved, I hope) similar problems.


Update: I found a way to make it work - thanks for your input.

Peristalsis fucked around with this message at 02:22 on Jan 13, 2021

Jaded Burnout
Jul 10, 2004


Peristalsis posted:

but I wondered if there's another best practice way to approach this, preferably keeping it in a Capybara feature test. With all the JavaScript and asynchronous stuff being done these days, others must have had (and solved, I hope) similar problems.

https://hackernoon.com/how-to-integrate-selenium-with-capybara-iq2n30dg

Chilled Milk
Jun 22, 2003

No one here is alone,
satellites in every home
Anyone got a preferred solution for blocking bots from spam creating accounts (Devise)? Google Captcha would be a last resort I guess, but I'd like to try something less icky first

aunt jenkins
Jan 12, 2001

My company is actually working on something in this space (including a devise integration) but it's not quite ready for primetime yet. I had this problem myself on another side project and ended up just putting in recaptcha and haven't had to deal with it since.

Adbot
ADBOT LOVES YOU

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

The Milkman posted:

Anyone got a preferred solution for blocking bots from spam creating accounts (Devise)? Google Captcha would be a last resort I guess, but I'd like to try something less icky first

Email verification? If you don't want emails then captchas may be your best option.

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