Ruby on Rails Controller action is a private method - ruby-on-rails

I am getting
private method `new' called for Reminder:Class
The Application trace is
app/controllers/reminders_controller.rb:27:in `new'
The new action is as follows
def new
#reminder = #current_user.reminders.build()
#title = "New Reminder"
respond_to do |format|
format.html # new.html.erb
format.json { render json: #reminder }
end
end
The Reminder Model is has follows
class Reminder < ActiveRecord::Base
belongs_to :user
belongs_to :assignment
attr_accessible :datetime, :sent_at, :status, :send_time
STATUSES = ["Not Sent", "Sending", "Sent", "Canceled"]
validates_presence_of :sent_at, :status, :user_id, :assignment_id
before_save :round_tine
def round_time
self.send_time = Time.at(t.to_i/(15*60)*(15*60))
end
end
I don't know how the method would be private. Thanks for the help in advance!
UPDATE: Added a method to the model. Error still occurs.

put mailer class name as ReminderMailer not just Reminder. That's the problem rails is not able to distinguish between two classes and it is identifying the new method for mailer class which has name Reminder and showing the error.

You probably have the private declaration somewhere above your new definition. Post the entirety of your reminders_controller or just remove that offending line.

Related

Duplicate two linked models Ruby

I want to duplicate my models 'Formulaire' and 'Question'. They have a has_may/belongs_to relation.
I'm able to duplicate the first model but I have a " NoMethodError in FormulairesController#duplicate
undefined method `save' for # " when I duplicate the second
My models :
Formulaire.rb
class Question < ActiveRecord::Base
belongs_to :formulaire
validates :nom, presence: true
end
Question.rb
class Formulaire < ActiveRecord::Base
has_many :questions, dependent: :destroy
end
formulaire_controller.rb
def duplicate
template = Formulaire.find(params[:id])
#formulaire= template.dup
#formulaire.save
#for question in #formulaire.questions
# question.dup
# question.save
#end
template2 = Question.where(formulaire_id: 47)
#question = template2.dup
#question.save
redirect_to #formulaire, notice: "Formulaire dupliqué"
end
def formulaire_params
params.require(:formulaire).permit(:name, :description,
questions_attributes: [:id, :nom, :typequestion, :image, '_destroy', photos_attributes:[:id],
answers_attributes:[:id, :content,'_destroy']]) if params[:formulaire]
#puts YAML::dump params
end
My view
formulaire/show.html.erb
<li class="Dupliquer"><%= link_to 'Dupliquer', duplicate_formulaire_path(#formulaire) %> </li>
routes.rb
resources :formulaires do
member do
get 'duplicate'
end
end
Thank you
Here in stackoverflow, I found it here:
If you want to copy an activeRecord object you can use its attributes to create new one like
you can have an action in your controller which can be called on link,
def create_from_existing
#existing_post = Post.find(params[:id])
#create new object with attributes of existing record
#post = Post.new(#existing_post.attributes)
render "your_post_form"
end
what's here: Rails clone copy or duplicate
I never used this gem, but it's for this, I'm going to leave it there and you'll see what you want.
https://github.com/amoeba-rb/amoeba
And also on reddit
def clone
#location = Location.find(params[:id]).dup
............
render :new
end
link: https://www.reddit.com/r/rails/comments/6phfy4/form_how_to_implement_a_clone_action/

rails error added to object but not raised

I'm doing an update of a form. I can't add my validation in my model for x reason, so I'm adding an error in my projects_controller in the method update. When I update it should raise the error and render :edit but it doesn't. Here is my method
def update
#project = Project.find(params[:id])
#stuff to update
#add error if no legal_media checked, unless if creative upload its own conditions
unless has_media?(#project.legal_option.authorized_format)
#project.legal_option.authorized_format.errors[:base] << "error message"
end
if #project.update_attributes(project_params)
redirect_to brief_path(#project.order.brief)
else
render :edit
end
end
the method has_media? returns false dans when I type #project.legal_option.authorized_format.errors[:base]I have my error message ["error message"].
But when I type #project.legal_option.authorized_format.valid?, it returns true
Any idea how I could make my method raise this error?
Thank you!
UPDATE trying to do the validation in the model :
Since the beginning I want to check that if my column custom_document in legal_option isn't nil (therefore the user uploaded it in the update method of the projects_controller), then, check if there is at least one media in legal_media.
Here are my models :
class LegalOption < ActiveRecord::Base
belongs_to :project
has_one :authorized_format, class_name: "LegalMedia", foreign_key: "legal_option_id"
accepts_nested_attributes_for :authorized_format
has_attached_file :custom_document
validates_attachment :custom_document, content_type: { content_type: "application/pdf" }
end
class LegalMedia < ActiveRecord::Base
belongs_to :legal_option
def self.formats
{all_media: "Tous Media", internet: "Internet", paper: "Presse papier", object: "Objets", television: "TV", radio: "Radio", cinema: "Cinéma", poster_campaign: "Affiches", :press_relation => "Relations Presse", :plv => "Publicité sur lieux de vente", :event => 'Evènementiel'}
end
end
When I did the validation in the beginning with a validate :has_media? My LegalOption.LegalMedia because legal_option_id is nil in legal_media
in the unless block, put the line:
render :edit and return
like:
unless has_media?(#project.legal_option.authorized_format)
#project.legal_option.authorized_format.errors[:base] << "error message"
render :edit and return
end
You should add a validation to the model in order for the valid? to do what you are looking for it to do.
If you look at the docs here, you'll see that valid? just runs all the validations. It doesn't check for any errors that you manually add to the object.
Rails convention dictates that validations shouldn't be implemented in the controller but rather in the model. More specifically, update_attributes just runs valid? after assigning the attributes, which itself just runs validations defined on the model. Any errors already on the model are cleared out beforehand.
If you re-write this as a custom validation on the model, update_attributes should behave as you expect:
class Project < ActiveRecord::Base
validate :legal_option_has_media
private
def legal_option_has_media
unless has_media? legal_option.authorized_format
errors.add :base, "error message"
end
end
end

ActiveRecord::RecordNotFound - in a descendant class' associated_controller#index

I am attempting to locate a parent object in a nested controller, so that I can associate the descendant resource with the parent like so:
# teams_controller.rb <snippet only>
def index
#university = Univeresity.find(params[:university_id])
#teams = #university.teams
end
When I call find(params[:university_id]) per the snippet above & in line 6 of teams_controller.rb, I receive ActiveRecord::RecordNotFound - Couldn't find University without an ID.
I'm not only interested in fixing this issue, but would also enjoy a better understanding of finding objects without having to enter a University.find(1) value, since I grant Admin the privilege of adding universities.
The Rails Guides say the following about the two kinds of parameters in a website:
3 Parameters
You will probably want to access data sent in by the user or other
parameters in your controller actions. There are two kinds of
parameters possible in a web application. The first are parameters
that are sent as part of the URL, called query string parameters. The
query string is everything after “?” in the URL. The second type of
parameter is usually referred to as POST data. This information
usually comes from an HTML form which has been filled in by the user.
It’s called POST data because it can only be sent as part of an HTTP
POST request. Rails does not make any distinction between query string
parameters and POST parameters, and both are available in the params
hash in your controller:
It continues a little further down, explaining that the params hash is an instance of HashWithIndifferentAccess, which allows usage of both symbols and strings interchangeably for the keys.
From what I read above, my understanding is that Rails recognizes both parameters (URL & POST) and stores them in the same hash (params).
Can I pass the params hash into a find method in any controller action, or just the create/update actions? I'd also be interested in finding a readable/viewable resource to understand the update_attributes method thats called in a controller's 'update' action.
Please overlook the commented out code, as I am actively searching for answers as well.
Thanks in advance.
Here are the associated files and server log.
Webrick
teams_controller.rb
class TeamsController < ApplicationController
# before_filter :get_university
# before_filter :get_team
def index
#university = University.find(params[:univeristy_id])
#teams = #university.teams
end
def new
#university = University.find(params[:university_id])
#team = #university.teams.build
end
def create
#university = University.find(params[:university_id])
#team = #university.teams.build(params[:team])
if #team.save
redirect_to [#university, #team], success: 'Team created!'
else
render :new, error: 'There was an error processing your team'
end
end
def show
#university = University.find(params[:university_id])
#team = #university.teams.find(params[:id])
end
def edit
#university = University.find(params[:university_id])
#team = #university.teams.find(params[:id])
end
def update
#university = University.find(params[:university_id])
#team = #university.teams.find(params[:id])
if #team.update_attributes(params[:team])
redirect_to([#university, #team], success: 'Team successfully updated')
else
render(:edit, error: 'There was an error updating your team')
end
end
def destroy
#university = University.find(params[:university_id])
#team = #university.teams.find(params[:id])
#team.destroy
redirect_to university_teams_path(#university)
end
private
def get_university
#university = University.find(params[:university_id]) # can't find object without id
end
def get_team
#team = #university.teams.find(params[:id])
end
end
team.rb
class Team < ActiveRecord::Base
attr_accessible :name, :sport_type, :university_id
has_many :home_events, foreign_key: :home_team_id, class_name: 'Event'
has_many :away_events, foreign_key: :away_team_id, class_name: 'Event'
has_many :medias, as: :mediable
belongs_to :university
validates_presence_of :name, :sport_type
# scope :by_university, ->(university_id) { where(team_id: team_id).order(name: name) }
# scope :find_team, -> { Team.find_by id: id }
# scope :by_sport_type, ->(sport_type) { Team.where(sport_type: sport_type) }
# scope :with_university, joins: :teams
# def self.by_university(university_id)
# University.where(id: 1)
# University.joins(:teams).where(teams: { name: name })
# end
def self.by_university
University.where(university_id: university_id).first
end
def self.university_join
University.joins(:teams)
end
def self.by_sport_type(sport_type)
where(sport_type: sport_type)
end
def self.baseball
by_sport_type('Baseball/Softball')
end
end
university.rb
class University < ActiveRecord::Base
attr_accessible :address, :city, :name, :state, :url, :zip
has_many :teams, dependent: :destroy
validates :zip, presence: true, format: { with: /\A\d{5}(-\d+)?\z/ },
length: { minimum: 5 }
validates_presence_of :name, :address, :city, :state, :url
scope :universities, -> { University.order(name: 'ASC') }
# scope :by_teams, ->(university_id) { Team.find_by_university_id(university_id) }
# scope :team_by_university, ->(team_id) { where(team_id: team_id).order(name: name)}
def sport_type
team.sport_type
end
end
views/teams/index.html.erb
Placed in gists for formatting reasons
rake routes output: (in a public gist)
enter link description here
rails console
You're not going to want to have both:
resources :universities #lose this one
resources :universities do
resources :teams
end
As for params... you have to give a param. So, when you go to http://localhost:3000/teams there are no params, by default. If you go to http://localhost:3000/teams/3 then params[:id] = 3 and this will pull up your third team.
Keep in mind the nomenclature of an index. The index action of Teams, is going to list all of the teams. All of them. There is no one University there, so what are you actually trying to find? If anything, you'd have, for your University controller:
def show
#university = University.find(params[:id])
#teams = #university.teams
end
so, the address bar will be showing http://localhost:3000/universities/23, right? params[:id] = 23, then you can find the teams associated with that university.

Rails: Method declared in Application controller, but undefined according to browser

... used in orderscontroller#new to create an array, which is used in a select method of a form field in views, which is supposed to add a new order
Hullo there,
So my error is this
Routing Error
undefined local variable or method `array_of_payment_types' for #
Now, I've got this select field for a form to submit a new order, but my browser won't load the page with the form:
<div class="field">
<%= f.label :pay_type %><br />
<%= f.select :payment_type_id, Order::PAYMENTS_TYPES,
:prompt => 'Select a payment method' %>
</div>
This is using an array that I am trying to create twice:
class Order < ActiveRecord::Base
...
belongs_to :payment_type
**PAYMENT_TYPES = array_of_payment_types**
validates :name, :address, :email
validates :pay_type, :inclusion => { :in => PAYMENT_TYPES }
...
**def array_of_payment_types
PaymentType.pluck(:pay_type_name)
end**
end
and here:
class OrdersController < ApplicationController
...
def new
#cart = current_cart
if #cart.line_items.empty?
redirect_to store_url, :notice => "Your cart is empty"
return
end
**#PAYMENT_TYPES = array_of_payment_types**
#hide_checkout_button = true
#order = Order.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #order }
end
end
...
end
while the method to create the array, which "plucks" the entries from the :pay_type_name column Payment_Type table, is declared both in order.rb and the ApplicationController, here:
class ApplicationController < ActionController::Base
protect_from_forgery
private
...
def array_of_payment_types
PaymentType.pluck(:pay_type_name)
end
end
Now I am trying to use the same process as other pieces of my application, just replicating stuff I have already done. For example, in OrdersController#new I've got
#cart = current_cart
current_cart is a method declared in the ApplicationsController and it works. So why doesn't array_of_payment_types also work?
Thanks for your help in advance :-)
Further information...
What I am trying to do with this is to create a new order, using a form, and one of the fields in the form enters a "pay_type" (or payment type in English). I want to present the user with options which is a list "plucked" from the entries in the PaymentType table, column :pay_type_name (I may be repeating myself, but no harm). But the new Order is created after the Order#new action, which is where I have created the array. Where/how should I create the array?
def array_of_payment_types in your Order class defines an instance method and you are trying to use it as a class method.
I'd just define array_of_payment_types as a class method instead and call Order.array_of_payment_types instead of the constant ARRAY_OF_PAYMENT_TYPES in your view.
You can always cache it in the class method, there's no need to use a constant for this.
def self.array_of_payment_types
#array_of_payment_types ||= PaymentType.pluck(:pay_type_name)
end
But, consider leaving the responsibility for the payment type array in the PaymentType class. The Order class shouldn't be the point of contact to retrieve data which is clearly under the control of another class.

Rails: difference between attr_accessor and attr_accessible

What is the difference? Also, why does this not work:
The variables such as base_path are not being set.
class Cvit < ActiveRecord::Base
attr_accessible :species,:program,:textup,:e_value,:filter,:min_identity,:cluster_dist,:fileup_file_name
attr_accessor :base_path, :fa_file, :text_file, :dbase, :source, :bl_file, :bl_sorted, :gff_file, :cvt_file, :db, :overlay_coords_gray
def initilize(*args)
super(*args)
end
def cvitSetup()
self.base_path = "blast_cvit/"
self.fa_file = "input.fa"
.
.
end
end
in the rails console the attributes get set correctly however when I try to do this:
controller:
def show
#cvit = Cvit.find(params[:id])
#cvit.cvitSetup()
#cvit.blast()
#cvit.generateGff()
#cvit.generateCvitImage()
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #cvit }
end
end
and in my view I reference #cvit.some_attribute.html_safe but that attribute is null so I get an error. Any ideas?
attr_accessor creates the getter method.attribute and setter method.attribute= for the specified attributes.
attr_accessible is from ActiveRecord::Base and "Specifies a white list of model attributes that can be set via mass-assignment." See documentation and example here.
EDIT:
As for your second question, I don't know. I tried this dummy code and it worked:
class Test
attr_accessor :base_path, :fa_file
def cvitSetup()
self.base_path = "blast_cvit/"
self.fa_file = "input.fa"
end
end
t = Test.new
t.cvitSetup
p t.base_path
#=> "blast_cvit/"
Are you sure that you properly instantiated your class?
attr_accessor simply creates a getter-setter method for an attribute.
attr_accessible specifies a white list of model attributes that can be set via mass-assignment, such as new(attributes), update_attributes(attributes), or attributes=(attributes). This has been excerpted from the link here

Resources