Rails display current controller errors - ruby-on-rails

The problem is really simple. I want to display error notifications outside simple_form_for tag for every controller in my app.
I use the following code:
- if #user.errors.present?
.alert-box.alert{ data: { alert: true } }
%div= t('simple_form.error_notification.default_message')
Which is OK, but only for one controller with #user variable. I want to know if there is some clever way to get this class instance variable (#user) without hardcoding the name. In each controller its different but it corresponds with current controller name #user for UsersController etc.
Thanks for the help. Unfortunately I can accept only one answer :)
Possible solution
I end up with helper method:
def errors_present?
# returns string like "UsersController" with support for name-spaced controllers
controller_name = controller.class.to_s.split('::').last
# extract out the "user" portion
prefix_name = controller_name.gsub(/controller/i, '').singularize.downcase
# is there a defined instance variable with this name?
i_var = controller.instance_variable_get(:"##{prefix_name}")
return i_var.errors.present? if i_var != nil
false
end
and view code:
- if errors_present?
.alert-box.alert{ data: { alert: true } }
%div= t('simple_form.error_notification.default_message')

If all of your controllers follow the same naming convention, then the instance variable name is the singular name of the controller. You can replace #user with the following:
instance_variable_get("##{controller.controller_name.singularize}")
If you move that into a helper method in application_helper.rb:
def controller_record
instance_variable_get("##{controller.controller_name.singularize}")
end
You can then reference controller_record in your view:
- if controller_record.errors.present?
.alert-box.alert{ data: { alert: true } }
%div= t('simple_form.error_notification.default_message')

If you're going to do this in a dynamic route than you'll need to ensure that the instance variable you use matches what can be inferred from the controller name. You can then use this in a helper method.
def controller_error_present
# returns string like "UsersController" with support for name-spaced controllers
controller_name = controller.class.to_s.split('::').last
# extract out the "user" portion
prefix_name = controller_name.gsub(/controller/i, '').singularize.downcase
# is there a defined instance variable with this name?
controller.instance_variable_get(:"##{prefix_name}") != nil
end
To be used like:
- if controller_error_present
.alert-box.alert{ data: { alert: true } }
%div= t('simple_form.error_notification.default_message')
As long as you initialize a #user variable in your controller than it will be picked up by the instance variable check.

Related

Method calling helper method response

I have a method in my helper that returns rows of results. I want to pass this to a method in my model which is called by another method.
Helper Method:
def transactions(account_id, start, finish)
response = get_call('/Accounts/Statements/' + account_id.to_s + '/' + start + '/' + finish)
response = JSON.parse(response.body)
#transactions = response.map {|txn| Transaction.new(txn)}
return #transactions
end
Model Method I wish to call helper method into:
def transaction
??
end
Model Method which requires the transaction method:
def to_pdf
title = #account.name
subtitle = "Account Statement: #{#month_name} #{#year}"
StatementPDF.new(title, subtitle, #transactions).render
end
In the initialise section of this method i have added:
#transactions = {}
The Prawn PDF is now being generated but without the rows of results. Let me know if any other information is required.
You can reference your helpers from models using ApplicationController.helpers method:
ApplicationController.helpers.transactions(...)
This will solve your problem but, in my opinion, it would be much better, if you refactor your code and don't use helpers from model.

Looping through object and blanking out fields

I have this constant to hold all dates fields:
DATE_FIELDS = [:a_effective_on, :a_expire_on,
:field_effective_on, :field_expire_on,
:line_manager_effective_on, :line_manager_expire_on,
:officer_effective_on, :officer_expire_on,
:regional_effective_on, :regional_expire_on]
I want to loop over an object and remove a date if it has a value.
Is this valid?:
#copy_to.DATE_FIELDS.each do |_date|
# remove dates here
end
I am getting a nil class for id error.
DATE_FIELDS.each do |field|
#copy_to.send("#{field}=".to_sym, nil) if #copy_to.send(field)
end
When you put a constant in your class like this, it exists at the class level. Access it with YourClassName::DATE_FIELDS if you're outside the class, or just DATE_FIELDS if you're inside the class.
This is how i would do it:
#instance method in your class
def clear_all_date_fields
atts = {}
DATE_FIELDS.each{|f| atts[f] = nil}
self.attributes = atts
end
Now you can do
#copy_to.clear_all_date_fields
note that this doesn't save #copy_to. You can save it afterwards, or put the save into the method (though i think it's better to have it not saving automatically).

Remove current model instance from AR:Relation

I am creating an instance method on a model which returns instances of the same model. How can I ensure that the instance of the model that the method is being called upon is not part of the output?
My code is like this at the moment:
def other_versions(include_current = true)
if include_current
Coaster.where(order_ridden: order_ridden)
else
#coaster.other_version_count // Need this to exclude the current instance.
end
end
I'm not sure I understood, but would this help?
def other_versions(include_current = true)
query = Coaster.where(order_ridden: order_ridden)
query = query.where("id != ?", id) unless include_current
query
end

How to initialize variable only if it is set up in controller?

How to initialize variable only if it is set up in controller???
Add the default value for the profile while defining the method and check if it is not the default value.
def initialize(profile = nil)
if profile
#profile = profile
#person = profile.person
end
end

How to mimic asp.net get set in rails

I am trying to mimic asp.net get{} set{} in rails, here is what i tried in my controller:
def get_segment=(segment)
if params[:s] != nil
segment = params[:s]
else
segment = "personal"
end
end
Then i am trying to access it like this:
#something = get_segment
But it always returns as nil.
How can i do this?
Thanks
Why are you using get segment=(segment)?
look like what you are wanting to do is test params[:s], so the = is uncessary, as is the segment parameter.
def get_segment
if params[:s] != nil
params[:s]
else
"personal"
end
end
I think this would give you what you want.
If you just want to mimic get{} set{} in C#, the property Segment
private string _segment;
public string Segment {
get { return _segment; }
set { _segment = value; }
}
is written as followed in Ruby:
# get
def segment
#segment
end
# set
def segment=(value)
#segment = value
end
# if you don't have additional logic, you can just write
attr_accessor :segment
Then you can use some_instance.segment to retrieve the value and some_instance.segment = some_value to modify the value.
According to your code sample above, you want to fetch s parameter with a default value if it doesn't exist. You should define a getter, not in the setter form as you have provided.
def get_segment # or just "segment"
params[:s] || "personal"
end

Resources