I want to know how to deal when one of my routes is given an incorrect parameter. For example, in this update
method, what if I were to receive text
but in reality, its a number. Should I deal with that in the model file? If so, how? I'm asking this cause I was told the following: "The post_params should be properly validated before being used."
def update
post = current_user.posts.find_by(id: params[:id])
if post.update!(post_params)
post_hash = post.as_json
post_hash.merge!(authorIds: params[:authorIds])
render json: {post: post_hash}, status: :ok
else
render json: {error: post.errors}, status: :unprocessable_entity
end
end
Post_params:
def post_params
params.permit(:text, :likes, :reads, :popularity, tags: [])
end
Post Model:
class Post < ApplicationRecord
# Associations
has_many :user_posts
has_many :users, through: :user_posts, dependent: :destroy
# Validations
validates :text, presence: true, length: { minimum: 3 }
validates :popularity, inclusion: { in: 0.0..1.0 }
def tags
if super
super.split(",")
end
end
def tags=(value)
if value.kind_of? Array
super value.join(",")
else
super value
end
end
def self.get_posts_by_user_id(user_id)
Post.joins(:user_posts).where(user_posts: { user_id: user_id })
end
end
CodePudding user response:
I would argue that validations are a model concern. It is best practice and encurreaged to use validators in the model layer, this is what they were built for.
And IMHO setting proper StrongParams
in the controller and using validations in the model fulfill the "The post_params should be properly validated before being used." requirement because if one of those checks fails then the data will not be persisted in the database.
To ensure that text
is not considered valid if it only includes a number you can extend the text
validation like this:
validates :text, format: { with: /\A[^1-9\.\s] \z/ },
length: { minimum: 3 },
presence: true
The regexp will match all strings that do not only contain numbers, dots (.
), and whitespace (like 12.5
) but will allow, for example, strings that contain word characters and numbers (like A10
). That might be enough for your use case or you might need to fine-tune the regex depending on your needs.