Validating by user_id in Rails - ruby-on-rails

I have this code that validates by user_id. If the category_name exists, this prevents the creation of a new Object. The code works but I don't believe this is best practice.
def create
#item_category = ItemCategory.new(item_category_params)
#item_category.user_id = current_user.id
search = ItemCategory.where(:name => #item_category.name,:user_id => current_user.user_id)
if search.blank?
respond_to do |format|
if #item_category.save
format.html { redirect_to :back, notice: 'Se ha creado la categoria' }
format.json { render action: 'show', status: :created, location: #item_category }
else
format.html { render action: 'new' }
format.json { render json: #item_category.errors, status: :unprocessable_entity }
end
end
else
respond_to do |duplicate|
duplicate.html { redirect_to #item_category, alert: 'Categoria Repetida' }
duplicate.json { render json: #item_category.errors, status: :unprocessable_entity}
end
end
end
Thanks.

It would be better to put the validation in your ItemCategory model...
class ItemCategory < ActiveRecord::Base
validates_uniqueness_of :name, :scope => :user_id
...
end

Related

Overriding Named Route Parameters edit and create

I'm having some issues with Overriding Named Route Parameters when I edit or create a post I get an error undefined method playerId for nil:NilClass. It still re-directs to the :id instead of the :playerId params only with create and edit methods.
Below, :playerId should be 101, but the 6 is the :id, not sure why it's picking it up.
SELECT `players`.* FROM `players` WHERE `players`.`playerId` = 6 LIMIT 1 [["playerId", "6"]]
Routes
resources :players, param: :playerId
Controller
def show
#player = Player.find_by(playerId: params[:playerId])
#season = PlayerStat.where("playerId = ?", #player.playerId).joins(:matches).where('matches.gameType = ?', 0).where('matches.teamId = ?', #player.teamId).group('year(matches.matchDate) DESC')
end
def edit
end
def create
#player = Player.new(player_params)
respond_to do |format|
if #player.save
format.html { redirect_to #player, notice: 'PLayer was successfully created.' }
format.json { render :show, status: :created, location: #player }
else
format.html { render :new }
format.json { render json: #player.errors, status: :unprocessable_entity }
end
end
end
def update
#player = Player.find params[:playerId]
respond_to do |format|
if #player.update(player_params)
format.html { redirect_to #player, notice: 'Player was successfully updated.' }
format.json { render :show, status: :ok, location: #player }
else
format.html { render :edit }
format.json { render json: #player.errors, status: :unprocessable_entity }
end
end
end
private
def set_player
#player = Player.find_by(playerId: params[:playerId])
end
def player_params
params.require(:player).permit(:playerId, :first_name, :last_name, :dob, :teamId, :jumper_no, :height, :weight, :image, team_attributes: [:teamId, :name], player_stats_attributes: [:playerId, :gameDate, :kicks, :marks])
end
undefined method playerId for nil:NilClass
The problem is params[:layerId] is nil upon a successful create or update because you aren't passing any playerId for the redirect_to. So #player is nil which resulted in that error. Changing your code to below should fix the error.
format.html { redirect_to player_path(#player.playerId), notice: 'PLayer was successfully created.' }
Same for update too.
you can define full routes like this:
get '/player/:playerId' => 'players#show'
get '/player/:playerId/edit' => 'players#edit'

Breaking a parameter and save the items separately

I need to save items separately coming from a form of a text field, but my code is saving these items duplicate form.
My controller
def create
#answer_option = AnswerOption.break_options(answer_option_params)
#answer_option = AnswerOption.new(answer_option_params)
respond_to do |format|
if #answer_option.save
format.html { redirect_to #answer_option, notice: 'Answer option was successfully created.' }
format.json { render :show, status: :created, location: #answer_option }
else
format.html { render :new }
format.json { render json: #answer_option.errors, status: :unprocessable_entity }
end
end
end
My model
class AnswerOption < ActiveRecord::Base
belongs_to :question
def self.break_options(var)
ugly_answers = var[:content].split /[\r\n]+/
ugly_answers.each do |answer|
AnswerOption.create!(content: answer)
end
end
end
Thanks!
def create
#answer_option = AnswerOption.break_options(answer_option_params)
end

belongs_to association not populating user_id

I had two models and wanted to add a belongs_to association. A user has_many Places. To do this I did the following:
1) Created a migration using rails g migration AddUserToPlace user:references
This created a user_id column in my places table with the following migration:
add_reference :places, :user, index: true
However when I create new places the user_id column remains blank.
What am I missing?
EDIT:
create action
def create
#place = Place.new(place_params)
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render action: 'show', status: :created, location: #place }
else
format.html { render action: 'new' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
The user_id is not filled by default. When create new Places make sure to include the user_id in the parameters for example;
#place = Place.new();
#place.create(name: "jahn", user_id: #current_user.id)
Also try to enforce the presence of user_id in the PlaceModel
validates :user_id, presence: true
you should have something like this;
def person_params
params.require(:place).permit(:user_id, :..., :....)
end
`User_id` should be passed from the form. Otherwise for example you could do this;
def create
#place = Place.new(place_params)
#place.user_id = current_user.id
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render action: 'show', status: :created, location: #place }
else
format.html { render action: 'new' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end

validates uniqueness with scope is not working

v3.2.1
Not sure why 'count' is coming up nil and index won't render, as 'count' it's been fine in every model until I do the uniqueness with scope validation.
Any suggestions?
MODEL
Class FeatureIcon < ActiveRecord::Base
belongs_to :user
validates_presence_of :img_size, :feature_name, :image, :user_id
validates_uniqueness_of :img_size, :scope => :feature_name
//paperclip interpolates stuff....
end
CONTROLLER
before_filter :load_user
def index
#feature_icons = #user.feature_icons.all
#feature_icon = #user.feature_icons.new
respond_to do |format|
format.html # index.html.erb
format.json { render json: #feature_icons }
format.js
end
end
def create
#feature_icon = #user.feature_icons.new(params[:feature_icon])
respond_to do |format|
if #feature_icon.save
format.html { redirect_to user_feature_icons_url, notice: 'successfully created.' }
format.json { render json: #feature_icon, status: :created, location: #feature_icon }
format.js
else
format.html { render action: "index" }
format.json { render json: #feature_icon.errors, status: :unprocessable_entity }
end
end
end
ERROR
NoMethodError in Feature_icons#create
undefined method `count' for nil:NilClass
Extracted source (around line #7):
6: <div class="count">
7: <div id="count" class="feed-count"><%= #feature_icons.count %></div>
8: </div>
In the create method, you instanciate #feature_icons (with an 's'), but in the view you're using #feature_icon (without the 's'), so #feature_icons is nil.
If the save fails, the line format.html { render action: "index" } renders the view index.htm.erb, but the method index in the controler is not not called. Try with
if #feature_icon.save
#... nothing to change
else
format.html do
#feature_icons = #user.feature_icons.all
render action: "index"
end
format.json { render json: #feature_icon.errors, status: :unprocessable_entity }
end
or
if #feature_icon.save
#... nothing to change
else
format.html { redirect_to :index }
format.json { render json: #feature_icon.errors, status: :unprocessable_entity }
end

get user_id Devise in nested form rails 3.1

I'm follow this tutorial http://railscasts.com/episodes/196-nested-model-form-part-1 for nested form.
I have 3 model the first user.rb:
class User
has_many :boards, dependent: :destroy
has_many :posts, dependent: :destroy, :autosave => true
accepts_nested_attributes_for :boards
accepts_nested_attributes_for :posts
end
The second model its board.rb
class Board
has_many :posts, :dependent => :destroy , :autosave => true
accepts_nested_attributes_for :posts
belongs_to :user
end
The third model its post.rb
class Post
belongs_to :user
belongs_to :board
end
I want create a new post since a board form and I have in boards_controller.rb
def new
#board = Board.new
#board.posts.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #board }
end
end
def create
#board = current_user.boards.new(params[:board])
#board.user = current_user
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
With this 2 methods I get every attributes of posts in my views. in my console if I put after create a board Post.first I get:
1.9.2-p290 :007 > Post.first
=> #<Post _id: 4f0b0b211d41c80d08002afe, _type: nil, created_at: 2012-01-09 15:43:29 UTC, user_id: nil, board_id: BSON::ObjectId('4f0b0b1b1d41c80d08002afd'), content: "hello post 2">
But If you take a look I get user_id: nil.
In normal model I get user id for example in create action of controller I put #post.user = current_user.id or #post.user = current_user
How Can I get the user_id in nested model post through from nested forms?
def create
#board = current_user.boards.new(params[:board])
##board.user = current_user - you don't need this line, since you create new board record using current_user object
# assign current_user id to the each post.user_id
#board.posts.each {|post| post.user_id = current_user}
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
You should be able to simply set the user_id property.
In your code you are assigning the current_user object to the association.
This should work:
def create
#board = current_user.boards.new(params[:board])
#board.user_id = current_user.id
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end

Resources