I'm running a rails app on heroku and recently switched to cloudflare for CDN for asset serving. My understanding was that once I use cloudflare, my assets (ie js,css,images) would be served from cloudflare and not from my own server but in my heroku logs I still see the requests for assets. Do I need to configure something in my rails app like setting the asset_host or something? Thanks.
vendredi 8 mai 2015
Validations, Nested Attributes and error handling when parent model isn't valid
Recently I added validations to one of the models in my application, and this seems to have caused a somewhat strange behaviour that I'm not handling properly in my code.
Here's a hypothetical example:
Clients
# name: string, phone: string, address: string
class Client < ActiveRecord::Base
has_many :transactions
accepts_nested_attributes_for :transaction, allow_destroy: true
validate :phone, numericality: true
end
Transactions
# p_date: date, location_id: integer
class Transaction < ActiveRecord::Base
belongs_to :client
end
This is how the controller would look like (again, have in mind that this is hypothetical):
PurchasesController
before_action :set_client, only: [:show, :edit, :update, :destroy]
def update
respond_to do |format|
if @client.update(client_params)
format.html { redirect_to clients_path, notice: 'Updated Succesfully' }
format.json { render :show, status: :ok, location: @client }
else
format.html { render :edit }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
def client_params
params.require(:client).permit(
:name, :phone, :address,
transaction_attributes: [:id, :p_date, :location_id, :_destroy]
)
end
def set_client
@client = Client.find(params[:id])
end
For new records this works fine, but when I run into old ones that do not conform to the new validation rules in the phone number, the nested attributes aren't saved, because it's parent record is no longer valid.
I'm trying to find a way how to handle such errors.
Currently, this would be handled by the else condition in if @client.update(client_params) in the controller. When an error happens, the controller renders the :edit action, which results in another error in my view, cause now the helper that generates the fields for the nested form is receiving a null value for @client.
The view in question that generates the error looks like this:
purchases/:client_id/edit.html.haml
= form_for @client, :url => {:controller => 'purchase', :action => 'update'} do |f|
- if @client.errors.any?
#error_explanation
%h2
The following errors were found:
%ul
- @client.errors.full_messages.each do |message|
%li= message
=render 'form', f: f
.actions
=f.submit 'Save Changes', :class => 'btn btn-md btn-primary'
The error says: "First argument in form cannot contain nil or be empty", which I'm assuming it is cause the render is not sending the id of the Client.
In case you're wondering, I'm using form_for @client, :url => {:controller => 'purchase', :action => 'update'} do |f| cause this view is not in the Client controller. if I omit the extra parameters, the form is sent directly to the Client controller, which has different code pertaining only to the Client model.
I've partially managed to work around this by using the following in the update action:
def update
respond_to do |format|
if @client.update(client_params)
# *snip*
else
format.html { redirect_to edit_purchase_path(@client) }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
This will redirect me back to the edit action, but no errors are printed. I get an identical page with the values used before I edited the values of the Transaction. I'm think there must be an easy way to send the errors back to the view, but I'm not sure where are these supposed to be used.
The "original" controller was generated by a scaffold, so the render :edit part is from the scaffolding itself. I'm aware my example could be somewhat vague (I'm just transcribing what I'm experiencing), so bear with me if this sounds a little odd. I'll gladly go into more detail if the information provided isn't enough.
What does this code, that looks like JavaScript object do?
@options = { query: {site: service, page: page} }
What does this do? In javascript this, I think would be object definition, however I cannot find what exactly it is in ruby. This would be the full code:
class StackExchange
include HTTParty
base_uri 'api.stackexchange.com'
def initialize(service, page)
@options = { query: {site: service, page: page} }
end
def questions
self.class.get("/2.2/questions", @options)
end
def users
self.class.get("/2.2/users", @options)
end
end
will_paginate: can't figure out how to customize inside bullets
I am trying to make a custom page list using will_paginate. I have succesfully created the previous and next buttons. I'm now trying to create the buttons in between but a having trouble figuring out how.
Here is my code for the previous and next buttons:
<ul class="pagination-styler">
<% if @options.previous_page %>
<li>
<%= link_to params.merge(:page => @options.previous_page), style: "aria-label: previous;" do %>
<i class="ba ba-left"></i>
<% end %>
</li>
<% end %>
Page <%= @options.current_page %> of <%= @options.total_pages %>
<% if @options.next_page %>
<li>
<%= link_to params.merge(:page => @options.next_page ), "aria-label" => "next" do %>
<i class="ba ba-right"></i>
<% end %>
</li>
<% end %>
</ul>
This renders the following:
I want to replace where it says "page 2 of 3" with icons I have that look similar to the previous and next buttons and will have specific page numbers. I can't find any helpers or way of doing this provided by will_paginate, but i'm sure there must be a way.
Does anyone know how to customize the actual link buttons? I'll need to wrap them in "li" and add the inside the links.
Rails 4 Internationalization I18n
My Rails App is on rails 4.0.2 and I have a problem switching translations with the locale variable and the params[:locale] from the url scheme following the official rails guide. I have a single page website at my site.
My routes for Internationalization:
scope "(:locale)", locale: /en|de/ do
#my routes here
end
My application controller
before_filter :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
#Rails.application.routes.default_url_options[:locale]= I18n.locale
end
# app/controllers/application_controller.rb
def default_url_options(options = {})
{ locale: I18n.locale }.merge options
end
The links to change the locale variables in the view:
<%= link_to_unless I18n.locale == :en, "English", locale: :en %>
|
<%= link_to_unless I18n.locale == :de, "Deutsch", locale: :de %>
What happens: the locale variable is set correctly but the translations are not switching. If I remove one of the translation files (currently for english and german) the languages switches to the remaining translation file. When I put back the other translation file and try to switch to it by changing the locale variable it never switches to the other language.
Why is my code not changing the translations?
How to remove bullet point when printing errors that are tied to base in rails 4 application?
I have a custom validator in a ROR 4 app which checks for a condition and then adds a custom error message to base:
errors.add(:base, "Please enter email as well as your city")
When the error displays on the screen, it has a bullet point in it. Can I remove the bullet point as the error is for the whole form and not a particular field? I do not want a generic css rule which removes bullet points from all errors added to base across the app. Is this possible? Thank you for your help.
Rails delete functionality is not working
I am completely new to Ruby On Rails, and going through this guide to build a basic application.
When I am trying to implement the delete functionality as mentioned in the document, I am seeing the show page.
I have below method in my controller:
def destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to articles_path
end
and below line in my page:
<td><%= link_to 'Destroy', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
Now when I click on the link, I am seeing below URL in browser:
Now now in this case I am seeing the show screen instead of getting an alert message and then deleting the record from my page.
I have followed this SO post - Rails 4 link_to Destroy not working in Getting Started tutorial
and verified that
//= require jquery
//= require jquery_ujs
elements are there in my application.js
Please tell me where I am doing mistake?