rails issue with naming convention and table - ruby-on-rails

I have an issue with rails with naming convention.
I have a database where i can't rename table so names are not in plural with inflector.
Today i wanted create model and controller for the table "wishlist__c" and the issue is here. I tried 3 times first by duplicating product model, controller.... and changing name then creating files myself and i still got the issue and then with rails g scaffold wishlist__c
The first error when i try to go to url:8080/wishlist__c/index :
Routing Error
uninitialized constant WishlistCController
wishlist__c_controller.rb exist. I notice after many test that the double '__' is a problem in rails. I rename it to wishlist_c_controller and the same with the model. the error message change to
--Solution: I forget to rename folder wishlist__c to wishlist_c in views folder
Thanks you all ! --
ActiveRecord::RecordNotFound in WishlistCController#show
Couldn't find WishlistC with 'id'=index
the code display under this is from wishlist_c_controller.rb:
def set_wishlist__c
#wishlist__c = ::WishlistC.find(params[:id])
end
How to solve it. I need to link my app to this table
edit:
Model wishlist_c.rb:
class WishlistC < ApplicationRecord
self.table_name = "wishlist__c"
end
wishlist_c_controller:
class WishlistCController < ApplicationController
before_action :set_wishlist__c, only: [:show, :edit, :update, :destroy]
# GET /wishlist__c
# GET /wishlist__c.json
def index
#wishlist__c = WishlistC.all
end
# GET /wishlist__c/1
# GET /wishlist__c/1.json
def show
end
# GET /wishlist__c/new
def new
#wishlist__c = WishlistC.new
end
# GET /wishlist__c/1/edit
def edit
end
# POST /wishlist__c
# POST /wishlist__c.json
def create
#wishlist__c = WishlistC.new(wishlist__c_params)
respond_to do |format|
if #wishlist__c.save
format.html { redirect_to #wishlist__c, notice: 'Wishlist c was successfully created.' }
format.json { render :show, status: :created, location: #wishlist__c }
else
format.html { render :new }
format.json { render json: #wishlist__c.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /wishlist__c/1
# PATCH/PUT /wishlist__c/1.json
def update
respond_to do |format|
if #wishlist__c.update(wishlist__c_params)
format.html { redirect_to #wishlist__c, notice: 'Wishlist c was successfully updated.' }
format.json { render :show, status: :ok, location: #wishlist__c }
else
format.html { render :edit }
format.json { render json: #wishlist__c.errors, status: :unprocessable_entity }
end
end
end
# DELETE /wishlist__c/1
# DELETE /wishlist__c/1.json
def destroy
#wishlist__c.destroy
respond_to do |format|
format.html { redirect_to wishlist__c_index_url, notice: 'Wishlist c was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_wishlist__c
#wishlist__c = WishlistC.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def wishlist__c_params
params.fetch(:wishlist__c, {})
end
end

Rails create RESTful routes based on controller and model. One of the routes would be get wishlist__c/:id which gets mapped to action show of WishlistCController. so when you hit the URL wishlist__c/index it takes index as the id.
If you want to render index page, create a route get wishlist__c/index and map it to index method of your controller. For the above to work you must hit the URL url:8080/wishlist__c/1 where 1 is your WishList ID. Replace it with values of id column of wishlist__c table.
Looking at your controller, you already have a route get wishlist__c/ mapped to the index method of your controller. So url:8080/wishlist__c/ should render index page for your model.

Related

Rails console issue with attr_encrypted

I am using rails attr_encrypted gem for encrypting data before storing in database. It works fine on my application as it encrypts with the provided key and decrypts it using the same key via my application. But when I create a instance with my rails console, it does not encrypt with the key that is provided in the application (
uses some random key each time maybe) and hence I am not able to decrypt it when I see that instance in my application.
Below picture shows that if I create the user with the same name twice in console, each time the encrypted data is different. I am following the tutorial on this page
When I try to access the page on my application, the user made by console are showing this error
Here is my code for my model.rb file and am using a temporary key for demo purpose:
class Model < ActiveRecord::Base
attr_encrypted_options.merge!(:encode => true)
attr_encrypted :user, key: "aMI9uV87sL46Nwv+8qeAOUp5nsvzp5C/FkVAOFkcCtk="
attr_encrypted :password, key: "aMI9uV87sL46Nwv+8qeAOUp5nsvzp5C/FkVAOFkcCtk="
end
Here is my controller code:
class ModelsController < ApplicationController
before_action :set_model, only: [:show, :edit, :update, :destroy]
# GET /models
# GET /models.json
def index
#models = Model.all
end
# GET /models/1
# GET /models/1.json
def show
end
# GET /models/new
def new
#model = Model.new
end
# GET /models/1/edit
def edit
end
# POST /models
# POST /models.json
def create
#model = Model.new(model_params)
respond_to do |format|
if #model.save
format.html { redirect_to #model, notice: 'Model was successfully created.' }
format.json { render :show, status: :created, location: #model }
else
format.html { render :new }
format.json { render json: #model.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /models/1
# PATCH/PUT /models/1.json
def update
respond_to do |format|
if #model.update(model_params)
format.html { redirect_to #model, notice: 'Model was successfully updated.' }
format.json { render :show, status: :ok, location: #model }
else
format.html { render :edit }
format.json { render json: #model.errors, status: :unprocessable_entity }
end
end
end
# DELETE /models/1
# DELETE /models/1.json
def destroy
#model.destroy
respond_to do |format|
format.html { redirect_to models_url, notice: 'Model was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_model
#model = Model.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def model_params
params.require(:model).permit(:user, :password, :host)
end
end

How to access todos in another controller rails 4.2?

I'm trying to learn RoR by creating an application, however, I have come across a problem and I'm not sure if my method is flawed or if it's the correct way to do it but I'm going about it slightly wrong. I think it has something to do with the variable being an instance variable and it's not called in my other controller but I'm not sure how to get it there?
Anyway the problem is -
I have a todos controller, models, views etc. set up via the scaffolding in Rails but I want to be able to display the todos to each user in their 'dashboard' so to speak when they log in. Therefore I assume I need the todos to be in the dashboard controller too, right?
Here's my dashboard controller
class DashboardController < ApplicationController
def home
#todos = current_user.todos
end
end
Here I'm calling my todos but they aren't showing when I call them in the view.
and my todos scaffold
class TodosController < ApplicationController
before_action :set_todo, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /todos
# GET /todos.json
def index
#todos = current_user.todos
end
# GET /todos/1
# GET /todos/1.json
def show
end
# GET /todos/new
def new
#todo = Todo.new
end
# GET /todos/1/edit
def edit
end
# POST /todos
# POST /todos.json
def create
#todo = current_user.todos.new(todo_params)
respond_to do |format|
if #todo.save
format.html { redirect_to #todo, notice: 'Todo was successfully created.' }
format.json { render :show, status: :created, location: #todo }
else
format.html { render :new }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /todos/1
# PATCH/PUT /todos/1.json
def update
respond_to do |format|
if #todo.update(todo_params)
format.html { redirect_to #todo, notice: 'Todo was successfully updated.' }
format.json { render :show, status: :ok, location: #todo }
else
format.html { render :edit }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /todos/1
# DELETE /todos/1.json
def destroy
#todo.destroy
respond_to do |format|
format.html { redirect_to todos_url, notice: 'Todo was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_todo
#todo = Todo.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todo_params
params.require(:todo).permit(:title, :item)
end
end
How would I go about displaying my todo items in the dashboard?
Thanks for any help
You just need to add
before_action :authenticate_user!
to DashboardController like the way you have it in TodosController .
Do you have a current user in the dashboard controller? You will need to decide how to handle that - either require sign in, or use an if else statement e.g.
def home
if current_user
#todos = current_user.todos
end
end

param is missing or the value is empty: module_list

I'm trying to enter a list of new modules and when I press 'new module list' which should take me to the form to fill out it throws up the error from the title. The application trace points at the bottom, the code inside 'def module_list_params' and also just above it where 'def set_student' is. I have no idea why it's doing it. I'm using ruby on rails.
class ModuleListsController < ApplicationController
before_action :set_module_list, only: [:show, :edit, :update, :destroy]
before_action :set_student, only: [:new, :create]
# GET /module_lists
# GET /module_lists.json
def index
#module_lists = ModuleList.all
end
# GET /module_lists/1
# GET /module_lists/1.json
def show
end
# GET /module_lists/new
def new
#module_list = #student.module_lists.new
end
# GET /module_lists/1/edit
def edit
end
# POST /module_lists
# POST /module_lists.json
def create
#module_list = #student.module_lists.new(module_list_params)
respond_to do |format|
if #module_list.save
format.html { redirect_to #module_list, notice: 'Module successfully created.' }
format.json { render :show, status: :created, location: #module_list }
else
format.html { render :new }
format.json { render json: #module_list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /module_lists/1
# PATCH/PUT /module_lists/1.json
def update
respond_to do |format|
if #module_list.update(module_list_params)
format.html { redirect_to #module_list, notice: 'Module list was successfully updated.' }
format.json { render :show, status: :ok, location: #module_list }
else
format.html { render :edit }
format.json { render json: #module_list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /module_lists/1
# DELETE /module_lists/1.json
def destroy
#module_list.destroy
respond_to do |format|
format.html { redirect_to module_lists_url, notice: 'Module list was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_module_list
#module_list = ModuleList.find(params[:id])
end
def module_list_params
params.require(:module_list).permit(:student_id, :title, :description, :credit_value)
end
def set_student
#student = Student.find_by(id: params[:student_id]) ||
Student.find(module_list_params[:student_id])
end
end
Rake routes screenshot
I believe your issue is the line before_action :set_student, only: [:new, :create]. set_student is being run when you go to the page with the form, but since there is no student_id included in the URL, it can't find anything to set it to.
To create a dependent object, there are two main ways: you can either have a form page tied to a specific parent object already, ie /students/4/module_lists/new, in which case submitting the form will create a module list tied to the student with an ID of 4. The other way is to have a general form not tied to any specific parent object, with some way of selecting a parent inside the form, eg a select or something. In that case the url would just be something like /module_lists/new.
If you want to go the first route, you'll want to nest the resources :module_lists inside of students. Check out the docs for how to do that, but it would basically look like
resources :students do
resources :module_list
end
And then in the link_to you click to go to that page, you'll need to pass in the student_id:
link_to 'Create Module List', new_student_module_list_path(#student)
For the second option, you can just remove :new from the before_action, change the new method to
def new
#module_list = ModuleList.new
end
And then add a way of picking which student to tie it to to the form.

Getting the ID of a Model that Uses Nested Routes and Permalinks in Rails

So I had my app set up with ids like so:
resources :studios do
resources :bookings
end
This gave me the route to the index (which later I'm going to use json for to get calendars for each studio.
studio_bookings GET /studios/:studio_id/bookings(.:format) bookings#index
This is good, but I wanted to get rid of the ID and use a permalink instead, just for a friendlier URL.
Change to:
namespace :studio, :path =>'/:permalink' do
resources :bookings
end
Now I'm getting
studio_bookings GET /:permalink/bookings(.:format) studio/bookings#index
Great! this is how I want my url to look, however, now the :id isn't anywhere in the route so... I get
Couldn't find Booking without an ID
It isn't even being passed. Is there a way to pass the :id in with the url without it being actually USED in the url? Otherwise, do I change the primary key from :id to :permalink in order to fix this?
I tried changing my controller from
#studio = Studio.find(params[:id])
to
#studio = Studio.find(params[:permalink])
but that gives me
Couldn't find Booking with 'id'=40frost
Which tells me what I'm doing isn't really meant to be done? It's trying to put the permalink as the id, so even though I'm telling rails to look for the permalink, it's still seemingly looking it up as an ID.
Hopefully my problem is clear: essentially - how can I pass the id so it knows which studio without displaying it in the URL. If there's some controller magic I can do instead that would be convenient.
Here's my controller for good measure
class Studio::BookingsController < ApplicationController
before_action :set_booking, only: [:show, :edit, :update, :destroy]
# GET /bookings
# GET /bookings.json
def index
#studio = Studio.find(params[:permalink])
#bookings = Booking.where("studio_id => '#studio.id'")
end
# GET /bookings/1
# GET /bookings/1.json
def show
end
# GET /bookings/new
def new
#booking = Booking.new
end
# GET /bookings/1/edit
def edit
end
# POST /bookings
# POST /bookings.json
def create
#booking = Booking.new(booking_params)
respond_to do |format|
if #booking.save
format.html { redirect_to #booking, notice: 'Booking was successfully created.' }
format.json { render action: 'show', status: :created, location: #booking }
else
format.html { render action: 'new' }
format.json { render json: #booking.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /bookings/1
# PATCH/PUT /bookings/1.json
def update
respond_to do |format|
if #booking.update(booking_params)
format.html { redirect_to #booking, notice: 'Booking was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #booking.errors, status: :unprocessable_entity }
end
end
end
# DELETE /bookings/1
# DELETE /bookings/1.json
def destroy
#booking.destroy
respond_to do |format|
format.html { redirect_to bookings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_booking
#booking = Booking.find(params[:permalink])
end
# Never trust parameters from the scary internet, only allow the white list through.
def booking_params
params.require(:booking).permit(:start_time, :end_time, :studio_id, :engineer_id, :title, :allDay)
end
end
You could just do
self.primary_key = 'permalink'
in your Studio model, or you could do
def index
#studio = Studio.find_by permalink: params[:permalink]
#bookings = Booking.where(studio_id: #studio.id)
end
depends if you just want to locally change the behavior or adress the Studio model by permalink always.
Hope that helps!

My Rails controller test is not inheriting the ApplicationController methods

I have an ApplicationController with a given method in the public area
def current_user
session[:user]
end
and another controller
ObjetosController < ApplicationController
which needs to access such method, and I'm getting a horrible error while running my tests (rake test:functionals):
NameError: undefined local variable or method `current_user' for
I'm using Ruby 2.0.0 and Rails 4.0. I've been travelling Google and StackOverflow for hours and hours and haven't found anything about it.
Maybe someone can give me a hint or help me search for an answer please?
If it helps, if I put crap inside ApplicationController, and run the test, it doesn't complain!!! It's like it was loading another version of this class...
Here my ObjetosController code:
class ObjetosController < ApplicationController
before_action :set_objeto, only: [:show, :edit, :update, :destroy]
# GET /objetos
# GET /objetos.json
def index
#objetos = Objeto.all
end
# GET /objetos/1
# GET /objetos/1.json
def show
end
# GET /objetos/new
def new
#objeto = Objeto.new
end
# GET /objetos/1/edit
def edit
end
# POST /objetos
# POST /objetos.json
def create
#objeto = Objeto.new(objeto_params)
respond_to do |format|
if #objeto.save
format.html { redirect_to #objeto, notice: 'Objeto was successfully created.' }
format.json { render action: 'show', status: :created, location: #objeto }
else
format.html { render action: 'new' }
format.json { render json: #objeto.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /objetos/1
# PATCH/PUT /objetos/1.json
def update
current_user
respond_to do |format|
if #objeto.update(objeto_params)
format.html { redirect_to #objeto, notice: 'Objeto was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #objeto.errors, status: :unprocessable_entity }
end
end
end
# DELETE /objetos/1
# DELETE /objetos/1.json
def destroy
#objeto.destroy
respond_to do |format|
format.html { redirect_to objetos_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_objeto
#objeto = Objeto.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def objeto_params
params.require(:objeto).permit(:nombre, :codigo_sgej)
end
end
Solved it.
In my ApplicationController class I was instantiating some classes dynamically defined for each environment. I was also using some constants defined per environment.
As this app hasn't been released to staging or production yet, I had such values defined only in config/environments/development.rb file. I added them to config/environments/test.rb and now it works!
I lost hours with this problem, I'm really dissapointed with rails (or ruby?) for not showing any error at all...

Resources