In Rails 3, I was able to do distinguish mounted (or mountable) engines from "other" engines by calling
MyEngine::Engine.class.mounted_path. This does not work in Rails 4 anymore. Based on this question, railties seem to have been deprecated.
How can I distinguish between mountable engines in Rails 4?
Rails::Engine.subclasses
This will return the mounted engines.
I used suggestions found [here][1] to create my own mounted_path method.
I put the following in an initializer file:
class Rails::Engine
def self.mounted_path
route = Rails.application.routes.routes.detect do |route|
route.app == self
end
route && route.path
end
end
Still looking for better answers.
[1]: Determine if Journey::Path::Pattern matches current page
Related
I want to match a specific route but not that route with any get query params.
Lets say I have a route like this:
get '/home', to: 'home#home
This works great for /home but how to I 404 /home?foo=bar?
If ?foo=bar makes no sense in your app it will have no effect at all.
Visiting /home?foo=bar will end seeing /home. This is quite a convention. Why do you need 404?
You can do this with an advanced constraint.
http://guides.rubyonrails.org/routing.html#advanced-constraints
class NoQueryParamsConstraint
def matches?(request)
request.query_parameters.blank?
end
end
get "/home", to: 'home#home', constraints: NoQueryParamsConstraint.new
is there a good way to make "friendly_ids" for the mongoid3 gem?
slugoid seems deprecated and KEY is not part of mongoid3 anymore.
Any answer will be very helpful
i'm using mongoid-slugify you just provide a method to generate slug, for example :
def generate_slug
self.name.parameterize
end
in that code i assume you have name field in your model
I'm probably missing something obvious, but I've got a logo I'd like to include in all of the emails I send from my app. I have a master layout I'm using for all of those Mailers. I assume there's a way to do keep it DRY and not have to add the line of code to attach the file in every mailer method. Can someone point me in the right direction or correct my line of thought.
Thanks!
Callbacks using before_filter and after_filter will be supported in a future Rails release:
http://github.com/rails/rails/commit/4f28c4fc9a51bbab76d5dcde033c47aa6711339b
Since they will be implemented using AbstractController::Callbacks, you can do the following to mimic the functionality that will be present in ActionMailer::Base once Rails 4 is released:
class YourMailer < ActionMailer::Base
if self.included_modules.include?(AbstractController::Callbacks)
raise "You've already included AbstractController::Callbacks, remove this line."
else
include AbstractController::Callbacks
end
before_filter :add_inline_attachments!
private
def add_inline_attachments!
attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
end
end
This includes the module that will be used in a future rails version, so the callback hooks available to you will be the same to ensure future compatibility. The code will raise when you try to upgrade to a Rails version that already includes AbstractController::Callbacks, so you will be reminded to remove the conditional logic.
I hacked a little something, it's not ideal, but it works.
If you use
default "SOMEHEADER", Proc.new { set_layout }
And then define set_layout
def set_layout
attachments.inline["logo.png"] = File.read("logopath.png")
attachments.inline["footer.jpg"] = File.read("footerpath.png")
"SOME HEADER VALUE"
end
Then because set_layout gets called to set the header, it also adds the inline attachments. It basically creates a callback for adding attachments.
An actual callback system in ActionMailer would be preferable, but this works too.
Thought I would share since I was looking for this answer on this question earlier today.
in the layout file that your mailer uses u can add the following
<%= image_tag('logo.png') %>
I am assuming that the mail being sent out is html or multipart.
Also you will need to make changes in the environment files. ActionMailer does not get a default base_url. For e.g in environments/development.rb I added the following
config.action_mailer.default_url_options = { :host => "localhost:3000" }
If you want to do it in a dRY manner (and as an attachment) maybe you could do something like
class MyMailer < ActionMailer::Base
default :attachment => File.read(File.join(Rails.root,'public','images','logo.png'))
end
I know you've asked about attaching inline images, but here's a different approach that achieves the same thing with less complexity..
Using inline base64 encoded images in the html layout - no attachments required!
Basically just change the src="..." of your logo image to the format:
<img alt="example logo"
width="32px"
height="32px"
src="data:image/png;base64,iVBORw0KGgoAAA....."/>
I use the online base64 encoder / decoder tool at http://www.base64-image.net for generating the complete <img /> tag
This approach has a few benefits:
- no attachment code, which makes the backend server code cleaner and easier to read
- no increase in email size - inline image attachments are converted to base64 anyway so this approach doesn't make the email payload any larger
- it's widely supported - if the receiving email client is showing html, it's pretty likely it also supports this method
Background: I've been doing RoR for about a year now, and am fairly comfortable with it, however, I know next to nothing about Javascript.
I've been playing around with some jquery autocomplete stuff in my rails app. I pretty much had a version working, but needed some tokenized fields too for a one to many relationship.
Right on cue - good old Ryan Bates does a railscast on it. So I start following the instructions.
Got a little bit nervous when I had to start installing 'jquery-rails' gem (I'd already installed jrails to get the other stuff working).
As suspected, it broke some stuff but I managed to get that working again.
Anyway, I got most of the way through the tutorial, and everything was going fine - I've got the tokenizer script to find the correct input field and it acts as expected. I've tested the json link too - that sends back all the right stuff.
However when I start typing in the text field - nothing happens, and when I view the console window it comes back with:
Uncaught TypeError: Cannot call method 'replace' of undefined
jQuery.jQuery.extend._Deferred.deferred.resolveWith
done
jQuery.ajaxTransport.send.callback
I can make guesses as to why this is going wrong - but any expert advice would be greatly appreciated.
(I should also add - I'm using formtastic too)
Thanks in advance.
Ok, finally figured it out.
It turns out that my author's name column is not name but rather author. So I needed to make a change inside the js.coffee script to override that default search of name.
The line you need to use is:
propertyToSearch: "author"
My whole book.js.coffee file now looks like this:
jQuery ->
$('#book_author_tokens').tokenInput '/authors.json'
theme: 'mac'
prePopulate: $('#book_author_tokens').data('load')
propertyToSearch: "author"
This actually fixed the error Uncaught TypeError: Cannot call method 'replace' of undefined
Of course, if you do use a different column name you will want to also edit the functions in the author.rb file to reflect that:
def self.tokens(query)
authors = where("author like ?", "%#{query}%")
if authors.empty?
[{id: "<<<#{query}>>>", author: "New: \"#{query}\""}]
else
authors
end
end
def self.ids_from_tokens(tokens)
tokens.gsub!(/<<<(.+?)>>>/) { create!(author: $1).id }
tokens.split(',')
end
Edit
Another thing I had to do for the fieldsto be prepopulated with the existing authors was change this:
= f.input :author_tokens, :data => { :load => #book.author }
To this:
= f.input :author_tokens, :input_html => { :data => { :load => #book.author } }
And then they would show up.
Hope this helps you.
I'm building an app on Rails 3 RC. I understand the point behind the _snowman param (http://railssnowman.info/)...however, I have a search form which makes a GET request to the index. Therefore, submitting the form is creating the following query string:
?_snowman=☃&search=Box
I don't know that supporting UTF encoding is as important as a clean query string for this particular form. (Perhaps I'm just too much of a perfectionist...hehe) Is there some way to remove the _snowman param for just this form? I'd rather not convert the form to a POST request to hide the snowman, but I'd also prefer it not be in my query string. Any thoughts?
You can avoid the snowman (now a checkmark) in Rails 3 by.... not using Rails for the search form. Instead of using form_tag, write your own as outlined in:
Rails 3 UTF-8 query string showing up in URL?
Rails helpers are great unless they're not helping. Do-it-yourself is good as long as you understand the consequences, and are willing to maintain it in the future.
I believe the snowman has to be sent over the wire to ensure your data is being encoded properly, which means you can't really remove the snowman input from forms. Since, it's being sent in your GET request, it will have to be appended to the URL.
I suppose you could write some javascript to clean up the URL once the search page loads, or you could setup a redirect to the equivalent URL minus the snowman. Both options don't really feel right to me.
Also, it doesn't seem there is any way to configure Rails to not output it. If you really wanted to get rid of it, you could comment out those lines in Rails' source (the committed patches at the bottom of railssnowman.info should lead you to the files and line numbers). This adds some maintenance chores for you when you upgrade Rails. Perhaps you can submit a patch to be able to turn this off?
EDIT: Looks like they just switched it to what looks like a checkmark instead of a snowman.
EDIT: Oops, back to a snowman.
In Rails 4.1 you can use the option :enforce_utf8 => false to disable utf8 input tag.
However I want to use this in Rails 3, so I monkey-patched my Rails. I put the following in the config/initializers directory.
# allow removing utf8 using enforce_utf8, remove after Rails 4.1
module ActionView
module Helpers
module FormTagHelper
def extra_tags_for_form(html_options)
authenticity_token = html_options.delete("authenticity_token")
method = html_options.delete("method").to_s
method_tag = case method
when /^get$/i # must be case-insensitive, but can't use downcase as might be nil
html_options["method"] = "get"
''
when /^post$/i, "", nil
html_options["method"] = "post"
token_tag(authenticity_token)
else
html_options["method"] = "post"
tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag(authenticity_token)
end
enforce_utf8 = html_options.delete("enforce_utf8") { true }
tags = (enforce_utf8 ? utf8_enforcer_tag : ''.html_safe) << method_tag
content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
end
end
end
end