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
Tea Bone
Feb 18, 2011

I'm going for gasps.
I have an old rails application whose database has had a sizeable number of tables/columns added and changed without using migrations. I've decided it's time for a big clean up and to get everything in line. Is there an easy way I can find discrepancies between the existing database and the migrations?

I've considered running db:schema:dump and deleting all migration files but I'm not sure if that's a good idea/possible negative repercussions?

Adbot
ADBOT LOVES YOU

Tea Bone
Feb 18, 2011

I'm going for gasps.
I’m trying to set up a relationship from a record to records it isn’t associated with. Imagine the following:

code:
class Reader<ActiveRecord::Base
	belongs_to :collections
	has_many :books, through: :collection
end

class Books<ActiveRecord::Base
	belongs_to :collections
	has_many :readers, through: :collections
end

class Collection<ActiveRecord::Base
	has_many :books
	has_many :readers
end
I want to define an association in reader which will return all the books not in their collection. I could use the following method:

code:
def books_not_in_collection
	Books.where(“id NOT IN (?)”, book_ids)
end
But that causes N+1 queries if it’s run on more than one reader, ideally I want to set it up as an association in reader. Is this possible?

Tea Bone fucked around with this message at 13:20 on May 15, 2019

Tea Bone
Feb 18, 2011

I'm going for gasps.
I need to generate PDFs from a template PDF supplied by a client. I’m currently using an ancient version of prawn to handle this as support for template PDFs was extracted from paperclip back in 2014.

I'm aware that theres the prawn-templates gem, but this feels like a temporary solution as there was a reason template support was dropped.

I’ve looked into switching over to wicked, but it looks like I’ll need to convert the supplied templates into html? This isn’t really ideal as the client updates the template semi-regular and it would be a huge pain to to re-create the html each time.

Are there any other alternatives out there?

Tea Bone
Feb 18, 2011

I'm going for gasps.

xtal posted:

Can you explain more about the problem? I think you could do that by using PDF forms (the best approach) or by overlaying a different PDF on top of it (a hacky workaround.) Parsing and generating a PDF according to a template in a way that preserves its appearance is extremely hard, and would be misusing the format, IMO.

Yeah sure, basically it's a web portal which generates a variety of pdfs for the end user to download based off of values they submit in a form. The client who owns the portal sends us a batch of template pdfs intermittently (every 3 months or so) usually with just minor copy changes, but occasionally entirely new layouts/requirements to re-order or add new fields to the generated pdf.

Ideally I want to just drop the drop the templates into a library and point the script to generate the output pdf to the template location.

At the moment I generate a new pdf with prawn and point prawn's template parameter at our template pdfs, then I draw text boxes at the required x,y coordinates to fill in the blanks.

I'm not too sure about the internal workings of prawn, but I suspect it's doing what you suggested in your second point (It just overlays my text boxes as a new PDF over the template PDF).

I agree that PDF forms are probably the way to go, but that means either us having to add the form fields to the template or getting the client to supply them with the fields in place already.

I'm starting to think perhaps generating the output PDF from another PDF is the wrong way of going about this. I'd perhaps be better off generating everything as an image then converting it to PDF? The output pdf doesn't need to be editable (or even selectable). But the templates are usually multiple pages long with only one or two of those pages requiring anything overlayed.

Tea Bone
Feb 18, 2011

I'm going for gasps.
I have two models with a relationship similar to this:

code:
class Card
	belongs_to :suit
end

class Suit
	has_one :ace, ->{where(value: ‘ace')}, class_name: Card
	has_one :king, ->{where(value:’king’)}, class_name:Card
end
a the moment if I run:

code:
card = Card.new
suit = Suit.new
suit.ace = c
suit.save
The suit and card both save, but the value on the card isn’t set to 'ace'. Is there a call back I can add to the has_one relationships which will automatically scope any cards when they’re added? I can over ride the ace= and king= methods in the Suit model but that seems messy.

Tea Bone
Feb 18, 2011

I'm going for gasps.

The Milkman posted:

Is there a reason you can't do

code:
suit = Suit.new
card = suit.build_ace


The Milkman posted:

Is there a reason you can't do

code:
suit = Suit.new
card = suit.build_ace

Thanks guys. I ended up flipping the relationship (so that suit belonged to card) as it made more sense for my use case and that ended up solving the issue.

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

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">

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

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!

Tea Bone
Feb 18, 2011

I'm going for gasps.
I'm trying to track the number of live users on my web app.

When a user connects to the app they subscribe to a "live users" action cable channel. I have a "Live Users" index on the admin back end.

Initially, I had it so when the admin went to the live user index the server would get the number of connections on the live users channel from Redis and use that to populate the index. Then any new subscriptions to the live user channel would broadcast to an admin channel and get added to the index. After running it like this for a few hours on my dev server things would start slowing down, and since I don't know too much about Redis or what's going on under the hood I switched to a different method.

My current solution, I have a live user model, on subscription to the live user channel a new record is created (and then removed on unsubscribe). Then the index page simply queries the database for current live users. This is working great on my dev server and has the added benefit of being able to add extra data about the connection (IP, browser language, current page etc) but it feels like there is a lot of database overhead here and I'm not sure how well it will work for production.

Does anyone have any suggestions how I can better handle this?

Tea Bone
Feb 18, 2011

I'm going for gasps.

kayakyakr posted:

Honestly, that kind of database overhead isn't bad at all. The other thing you might try is not deleting records, just keeping them around and updating sub/unsub dates.

You could also go to a key:value store that might be a bit faster than postgres with the same benefits of having that on the DB.

Thanks. I just wanted to check I wasn't breaking some cardinal sin by adding and deleting rows that much. After doing a bit more research into Redis, I think a key:value store is probably the best way forward but I'm happy to push that down the line for the time being as the database method is working fine.

Tea Bone
Feb 18, 2011

I'm going for gasps.
How are you running the server?

Are you using an IDE or magically rubbing it through terminal with "rails s"?

Either way, when you goto localhost:3000, do you see anything happening in the server console? If so, you should be able to see which controller and action the server is routing the request to.

Also, try putting at the end of your static_controller index action:
code:
render inline: 'hello world'
If then "hello world" shows up when you goto localhost:3000 then there's something up with your views.

Tea Bone
Feb 18, 2011

I'm going for gasps.
I'm running an API server with rails. Calls to the server are made from app.mysite.com and mysite.com. The api runs from api.mysite.com

I've installed rack-cors and have the following config in my initializer:
code:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'mysite.local', 'mysite.com', 'app.mysite.local', 'app.mysite.com'
    resource '*', headers: :any, methods: [:get, :post, :patch, :put, :delete], credentials: true
  end
end
Everything works great on my local server. On the live server, I get the error:

quote:

The 'Access-Control-Allow-Origin' header has a value 'https://app.mysite.com' that is not equal to the supplied origin.
when I try and call the API from mysite.com. Oddly if I visit the API manually (i.e api.mysite.com/user.json) that seems to clear the error and everything works from mysite.com as expected.

I've tried replacing the origins array with a regex:
code:
/(.*\.)?mysite\.com/
But that gives me exactly the same error.
The only way I can successfully make the API calls from mysite.com is if I remove the subdomain references from the origins array completely.

I'm assuming I've misunderstood something fundamental about how rack-cors works.
Does anyone have any ideas?

Tea Bone
Feb 18, 2011

I'm going for gasps.

Gmaz posted:

I wonder if it could be a http/https thing. Is your local server http?


Gmaz posted:

I wonder if it could be a http/https thing. Is your local server http?

Thanks guys. I finally got to the bottom of it. Chrome was caching the first Access-Control-Allow-Origin header, so whichever domain I made the first call from was stopping the second domain working. Looks like it was working locally because my local server wasn't including an ETag header, so no caching.

Adbot
ADBOT LOVES YOU

Tea Bone
Feb 18, 2011

I'm going for gasps.
Is there a way to skip a file in the public directory?

Basically, I'm serving a react app from public/index.html which works great.
In development, though I'd like requests to hit my rails controller instead (so I can proxy the request to my local npm development server).
The trouble I'm having is if the index.html file exists in public then rails just automatically serves that and never touches the controller.

It's not a huge issue since I can just rename or delete the index file in development, but at some point I'm inevitably going to forget to add it back and push to live without it.

edit nevermind
config.public_file_server.enabled = false is what I wanted

Tea Bone fucked around with this message at 16:46 on Jun 30, 2022

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