how to include a class which is not a model in controller - ruby-on-rails

I have added class ContactRequest in home_helper.rb
module HomeHelper
class ContactRequest
include ActiveModel::Model
attr_accessor :name, :email, :phone, :message, :captcha
validates :name, presence: true,length: {in:2..255}
validates :email, presence: true, length: {in:6..255}
validates :message, presence: true
validates :phone, presence: true
validates :captcha, presence: true
end
end
This class basically is to be used to bind dat from a JSON POST to an object which then I can use for
Verifying Captcha
Sending the contact information from this object as an email via SendGrid
hence, I do not have any needs to persist the information.
However I get an error when the relevant method of the controller is called
def contact
#contactReq = ContactRequest.new(JSON.parse(params[:json]))
logger.debug "ContactRequest: #{#contactReq.attributes.inspect}"
for this line I see in the logs
NameError (uninitialized constant HomeController::ContactRequest):
app/controllers/home_controller.rb:6:in `contact'
isn't the home_helper available to the view and this controller? Or should I put this class in concerns directory?

You need to add the module name in front of the classname HomeHelper:
def contact
#contactReq = HomeHelper::ContactRequest.new(JSON.parse(params[:json]))
...
end

Related

Rails inherit class shared attributes on build

assuming i have two models human and male, they both have similar attributes but not all the attributes, for example:
class Human < ApplicationRecord
has_many :males
validates :name, presence: true
validates :age, presence: true
validates :date_of_birth, presence: true
validates :identity, presence: true
end
class Male < ApplicationRecord
belongs_to :human
validates :name, presence: true
validates :age, presence: true
end
now what i want to do is when i use human.males.build i want the new male instance to inherit the shared attributes like name and age
instead of using this behavior human.males.build({attributes})
I'm thinking of overwriting the initialize (alias of build) method of Male model which will do the trick:
def initialize(attributes = {}, &block)
super(attributes, &block)
self.name = human.name unless attributes[:name].present?
self.age = human.age unless attributes[:age].present?
end
But honestly, I don't think this is a safe and generic way for the problem.

Validate for params for separate forms for 1 model

I have an issue with a model. I have a model that is updated through 2 forms (as 2 people need to enter separate data). Form 1 contains the first half of the required data and therefor only that data needs to be validated there.
I am having trouble finding a way to validate only the data entered in form 1. Below you'll find my subscription.rb model file.
class Subscription < ActiveRecord::Base
# werkgever form
if form_id == 'form1'
validates :email, presence: true
end
# werknemer form
if form_id == 'form2'
validates :name, presence: true
validates :city presence: true
end
end
I need the if statements to contain something that would make it so that only the values beloging to that form are validated so that i dont get errors on form2 when updating and vice versa.
I hope this is clear enough. Any help is appreciated.
Thanks.
You could set validations with condition:
attr_accessor :form_type
validates :email, presence: true, :if => :werkgever_form?
def werkgever_form?
form_type == 'werkgever'
end
:form_type is a virtual attribute, which is not saved in the database and needed only for validations. You can set this attribute as a hidden field in each form:
<%= form.hidden_field :form_type, 'werkgever' %>
attr_accessor :form_type
validates :email, presence: true, if: :check_if_form_one
validates :name, presence: true, unless: :check_if_form_one
validates :city presence: true, unless: :check_if_form_one
def check_if_form_one
/* Add your condition here
example: form_type == 'form1' */
end
You can set form_type from controller method or view page.

How can I skip validations of superclass in Rails 4?

I have pretty big RoR app.
There is superclass named User.
class User < ActiveRecord::Base
validates :email, presence: true
end
Also I have class Client which inherited by User
class Client < User
with_options(on: [:personal_info]) do |pi|
pi.validates :first_name,
:last_name,
:email,
:mobile_phone,
:landline_phone,
presence: true
pi.validates :primary_email,
email_format: {
message: "doesn't look like an email address"
}
end
end
When I create Client's object I got 2 errors that "Email can't be blank."
How can I disable or skip validates of superclass??
Remove validations in superclass is impossible.

Overriding presence true in User model

I have the following in my models/user.rb:
validates :company, presence: true
validates :title, presence: true
I have a secondary view where I want to create a user but not require this user to enter a company and a title. How would I do that without modifying the main user.rb?
This is for Rails 3.2
You can do by declaring custom validations the way #BroiSatse has answered or when saving the user you can pass validate: false as argument, do this way
#user.save(:validate => false)
I usually do sth like:
class User < AR::Base
validates :company, :title, presence: true, if: :validate_company_and_title?
def validate_company_and_title?
#validate_company_and_title.nil? || #validate_company_and_title
end
def skip_company_and_title_validation!
#validate_company_and_title = false
end
end
Then in your controller create action for given view you can do:
#user.skip_company_and_title_validation!

Strong parameters in Ruby

I'm getting the error message about strong parameters. I think it's just that rails 4 doesn't use attributes anymore. the code for my toy.rb is:
class Toy < ActiveRecord::Base
attr_accessible :name, :price, :vendor
validates :name, :presence => true
validates :price, :presence => true
validates :price, :numericality => true
validates :vendor, :presence => true
end
how can I change this to strong parameters?
EDIT: I used a different rb i changed it to employees and this is what I have:
class Employee < ActiveRecord::Base
params.require(:employee).permit(:first, :last, :salary, :salary, :ssn)
validates :first, :presence => true
validates :last, :presence => true
validates :salary, :presence => true
validates :salary, :numericality => true
validates :ssn, :presence => true
end
It's still telling me "ndefined local variable or method `params' for #"
The code you need is
params.require(:toy).permit(:name, :price, :vendor)
You will put this in your controller. Typically, you create a private method:
def create
Toy.create(toy_params)
end
private
def toy_params
params.require(:toy).permit(:name, :price, :vendor)
end
See http://guides.rubyonrails.org/getting_started.html#saving-data-in-the-controller for more information.
Edit
I think I might have misled you with my original answer. The code goes in the controller, not the model.
Strong params are designed to help your controller send specific data to your model. It's meant to protect your app against unauthorized data being passed:
#app/controllers/toys_controller.rb
Class ToysController < ActiveRecord::Base
def new
#toy = Toy.new #-> creates a blank AR object
end
def create
#toy = Toy.new(toys_params) #->creates new AR object (populating with strong params)
#toy.save
end
private
def toys_params
params.require(:toys).permit(:your, :params, :here)
end
end

Resources