forbidden attribute error rails 4 Carrierwave - ruby-on-rails

Have a issue with a controller file which i have narrowed down to a method
Controller
def create
#gallery = Gallery.new(params[:gallery])
if #gallery.save
flash[:notice] = "Successfully created gallery."
redirect_to #gallery
else
render :action => 'new'
end
end
private
def gallery_params
params.require(:gallery).permit(:name, :gallery, :gamepic)
end
end
the problem is that there is no attr_accessible in the controller or the model
model
class Gallery < ActiveRecord::Base
has_many :gamepics
private
def gallery_params
params.require(:gallery).permit(:name, :gallery, :gamepic)
end
end

Try passing the strong parameters method into Gallery.new instead of params[:gallery].
My understanding of this is that, the hash returned from that method is what should be used anyways. So you'd have:
#gallery = Gallery.new(gallery_params)
If you only need certain params from your :permit call, just make a new strong params method and use that one.

Related

Nested resources, simple_form_for

I am trying to create an app where I have Events and each event would have many sales. When a new sale is created it automatically gets an event ID it belongs to. Could somebody please review this and tell me if I am doing something wrong, because I think the way am creating simple_form for the nested model(Sale) is a bit incorrect. Also I am not sure if it should be this way or I ve done something wrong, but when I am accessing nested children the url looks like this
.../events/4/sales/1
.../events/3/sales/1
.../events/5/sales/1
but I would expect it to be like this ?!
.../events/4/sales/1
.../events/4/sales/2
.../events/4/sales/3
Here is my controller and model for Events
class Event < ApplicationRecord
has_many :sales, dependent: :destroy
end
.
class EventsController < ApplicationController
def index
#events = Event.all
end
def new
#event = Event.new
end
def create
#event = Event.new(event_params)
if #event.save
redirect_to #event
else
redirect_to events_path
end
end
def show
#event = Event.find(params[:id])
#sales = #event.sales
end
private
def event_params
params.require(:event).permit(:name, :comment, :event_disscount)
end
end
.
Here is my controller and model for Sales
class Sale < ApplicationRecord
belongs_to :event
has_many :sale_items
accepts_nested_attributes_for :sale_items, allow_destroy: true
end
.
class SalesController < ApplicationController
def new
#sale = Sale.new(event_id: params[:event_id])
#event = Event.find_by(id: params[:event_id])
end
def create
#event = Event.find(params[:event_id])
#sale = #event.sales.create(params[:sale].permit(:receipt_email))
if #sale.save
redirect_to #event
else
redirect_to new
end
end
end
routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
resources :events do
resources :sales
end
root 'events#index'
end
And this is how I use simple_form for sale(new)
<%= simple_form_for([#event, #sale]) do |f| %>
My main concern is the 'new' action in Sales controller, whats the best way to create a nested resource with the id of its parent, and then passing this object to the simple_form?!
Thank you in advance
Your question is too broad. Basically you're doing it all right, however, with some improvements on the code it will be easier to find possible problems.
is it correct the way I am creating new sale?
Some improvements over your SalesController:
Create private method sale_params which will sanitize input params from your form. You did it for events already - why not to do it here too?
Since that controller works in the scope of event, params[:event_id] is set for every action. So create a before_action filter which will set your #event variable.
Method create saves the model to the database, so calling save after it makes no sense.
In case of failure on saving #sale to the db redirecting to new is not reasonable. In that case everything user typed in the form will be lost, validation error won't be shown and it will look like a glitch of your app. Render new template instead with the same #sale.
This is how I would rewrite your controller:
class SalesController < ApplicationController
before_action: :set_event
def new
#sale = #event.sales.build
end
def create
#sale = #event.sales.build(sale_params)
if #sale.save
redirect_to #event
else
render action: :new
end
end
private
def sale_params
params.require(:sale).permit(:receipt_email, sale_items_attributes: [])
end
def set_event
#event = Event.find(params[:event_id])
end
end

Upload base64 Image with Paperclip - Rails 4

I am relatively new to Rails and would appreciate any help.
My website accepts a signature image in base64 format and I am trying to use a Paperclip adaptor to decode the image and save it to my form model as the :signature attribute. I am using the advice given here (and here) which advises to use the following code:
In model:
class Thing
has_attached_file :image
In controller:
def create
image = Paperclip.io_adapters.for(params[:thumbnail_data])
image.original_filename = "something.gif"
Thing.create!(image: image)
...
end
My assumption is that Thing.create! is setting the value of Paperclip's model attribute :image to be the value of the image variable whilst creating and saving a new Thing object. I tried to implement the same code in my FormsController (create action) before #form.save, but am receiving this error:
undefined method `before_image_post_process' for #<Class:0x007f94a2a26de8>
My FormsController:
class FormsController < ApplicationController
before_action :logged_in_user
before_action :admin_user, only: :destroy
def index
#forms = Form.all #paginate
end
def show
#form = Form.find(params[:id])
end
def new
#form = Form.new
end
def create
#form = Form.new(form_params)
# Paperclip adaptor
signature = Paperclip.io_adapters.for(params[:base64])
signature.original_filename = "something.png"
# Attempt to submit image through Paperclip
#form.signature = signature
if #form.save
flash[:success] = "The form has been successfully created!"
redirect_to #form
else
render 'new'
end
end
def edit
#form = Form.find(params[:id])
end
def update
#form = Form.find(params[:id])
if #form.update_attributes(form_params)
flash[:success] = "Form has been updated!"
redirect_to #form
else
render 'edit'
end
end
def destroy
Form.find(params[:id]).destroy
flash[:success] = "Form deleted"
redirect_to forms_path
end
private
def form_params
params.require(:form).permit(:first_name, :last_name, :email, :phone, :address, :member_type, :base64)
end
end
This is my Form model:
class Form < ActiveRecord::Base
has_attached_file :signature
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
end
Assuming that you're using the Rails form helpers over in your view, and based on your form_params list, the :base64 key won't be at the top level of your params hash, but rather one level down at params[:form][:base64]

Keep Receiving an "Unknown attribute=user_id" error

First time poster, long time lurker here. I have a Users model and controller for a little video game application for Rails that I'm currently making. So I've read a couple of answers on here regarding this issue, but none of the answers really seem to have helped me. People have suggested adding a "user_id" column to my Users table, but my point of contention is, I thought the "user_id" was automatically made in Rails? Even if I use a user.inspect, I still see a user_id=7show up on the page. However, I still get the unknown attribute error when attempting to create a game and assign to the current user. Any help would be most appreciated in pinpointing the cause and solution to this. Thanks!
app/controllers/users_controller.rb:
class UsersController < ApplicationController
skip_before_filter :require_authentication, only: [:new, :create]
def index
#users = User.all
end
def show
end
def new
#user = User.new
end
def edit
#user = current_user
end
def create
#user = User.create!(user_params)
session[:user_id] = #user.id
redirect_to users_path, notice: "Hi #{#user.username}! Welcome to DuckGoose!"
end
def update
current_user.update_attributes!(user_params)
redirect_to users_path, notice: "Successfully updated profile."
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to users_url, notice: 'User was successfully destroyed.'
end
private
def user_params
params.require(:user).permit(:username, :firstname, :lastname, :email, :password, :password_confirmation)
end
end
app/config/routes.rb:
NkuProject::Application.routes.draw do
resources :users do
resources :games
end
resources :sessions
resources :games
get "sign_out", to: "sessions#destroy"
get "profile", to: "users#edit"
root to: "sessions#new"
end
app/controllers/games_controller.rb
class GamesController < ApplicationController
def new
#game = Game.new
end
def index
#games = Game.all
end
def destroy
#game = Game.find(params[:id])
#game.destroy
redirect_to games_url, notice: 'Game was successfully deleted.'
end
def create
#game = current_user.games.build(game_params)
if #game.save
redirect_to #game, notice: "Game successfully added"
else
render :new
end
end
def show
#game = Game.find(params[:id])
end
private
def game_params
params.require(:game).permit!
end
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :require_authentication
def current_user
#current_user ||= User.find_by(id: session[:user_id]) if session[:user_id].present?
end
helper_method :current_user
def require_authentication
if current_user
true
else
redirect_to new_session_path
end
end
end
I'm sure I'm missing some code to put in for reference, but if I need anything else please let me know.
Looking at the way your controller actions are defined, I can safely say that User and Game have a 1-M relationship, i.e.,
class User < ActiveRecord::Base
has_many :games
end
class Game < ActiveRecord::Base
belongs_to :user
end
Now, based on that games table must have a field named user_id. Rails is not going to create it for you unless you specify it. You need to add field user_id in games table by creating a migration for the same. Right now, it doesn't seem like you have user_id foreign_key field in games table. Hence, the error while saving games record.

Clarification about using form_for

While creating a search form I am facing a problem. I am getting the following error:
undefined method `model_name' for NilClass:Class
This is my view file:
"datepicker" %>
This is my clients_controller.rb:
class ClientsController < ApplicationController
def newClients
end
end
And this is my model client.rb:
class Client < ActiveRecord::Base
# attr_accessible :title, :body
end
I am confused in using form_for parameter. Can any one explain it briefly how and why to use form_for parameter?
Edit 1
I have modified my controller as
class ClientsController < ApplicationController
def search
redirect_to root_path
end
end
Once i click submit button it showing error as
No route matches [GET] "/search"
You are missing something here. Let me explain.
In your controller you don't need to define a custom method (called newClients) since Rails conventions suggest to use the following:
class ClientsController < ApplicationController
# GET /clients
def index
#clients = Client.all
end
# GET /clients/:id
def show
#client = Client.find(params[:id])
end
# GET /clients/new
def new
#client = Client.new
end
# POST /clients
def create
#client = Client.new(params[:client])
if #client.save
redirect_to :back, success: "Successfully created..."
else
render :new
end
end
# GET /clients/:id/edit
def edit
#client = Client.find(params[:id])
end
# PUT /clients/:id
def update
#client = Client.find(params[:id])
if #client.update_attributes(params[:client])
redirect_to :back, success: "Successfully edited..."
else
render :edit
end
end
# DELETE /clients/:id
def destroy
#client = Client.find(params[:id]).destroy
redirect_to :back, success: "Successfully deleted..."
end
end
And finally, in order for your form_for to work properly, you need to pass it an instance of a class:
form_for #client
where #client is Client.new in your case.
First of all in your controller please follow Rails naming conventions. The method name should be new_clients or new.
def new
#client = Client.new
end
Your view name should be new.html.erb.
You are not defining #client in your controller, but in the view you are using it.

build_association working?

I have two models with a one-to-one association.
class User < ActiveRecord::Base
has_one :setting
end
class Setting < ActiveRecord::Base
belongs_to :user
end
Each model has plenty of fields and user is used quite extensively by a non rails external server, which is why I have separated the tables.
I am trying to use the build_association but all I get is undefined method `build_setting' for nil:NilClass. I want to do this because I want a single form with fields from both models to setup a new user.
In my user controllers new method I try this:
def new
#user = User.new
#setting = #user.setting.build_setting
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #user }
end
end
Which throws:
NoMethodError in UsersController#new
undefined method `build_setting' for nil:NilClass
Why? According to the api docs this is the way to do it.
Doing this seems to work, but its not the right way (or is it?):
def new
#user = User.new
#setting = Setting.new
#user.setting=#setting
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #user }
end
end
You need to use:
#setting = #user.build_setting
This is after an edit, so if you like this answer, accept Mahesh's below.
In your users model add
class User < ActiveRecord::Base
has_one :setting
validates_associated :setting
end
and then use
#setting = #user.build_setting

Resources