ruby on rails - Validating foreign key constraints -
i have 2 tables data_elements
, types
. types used store static list of types , has 2 columns: id
, name
. data_elements
has type
column should referencing id
in types
table. when dataelement
created via html form, list of types shown drop down, , works. need create dataelement
via api call, , validate type
passed parameter rest call in fact 1 of types stored in types
table. haven't been able figure out way it. i'd appreciate suggestions.
model way (with validation)
if want handle on model side, suggest create "custom attribute", in way won't impact existing functionality existing type
field. along these lines:
app/models/data_element.rb
def type_name=(value) found_type = type.find_by(name: value.to_s) self.type = found_type unless found_type.nil? end def type_name type.try(:name) end
app/controllers/data_elements_controller.rb
def create @data_element = dataelement.new(data_element_params) @data_element.save end def data_element_params # please ensure `type` not present in `permit` params.require(:data_element).permit(:whatever, :type_name, :other_field) end
in way, handle type_name
if attribute. don't need validation: if no type
found name, don't change value (you can report errors or validate, in case).
obviously, if use type
too, @data_element.update_attributes(type_name: 'foo', type: type.first)
you'll end weird results (type
assignment comes after you'll end type.first
instead of type
named 'foo'
), if use type_name
in assignment, ensure type
not used in moment, shouldn't problem, don't put in permit
params
controller way
my first suggestion "do not use type" table/model name. type
column used rails single table inheritance, that's main reason. calling dataelementtype ok, in case choice.
about question, there various ways that, first 1 come in mind is
app/models/type.rb
class type validates :name, presence: true, uniqueness: { case_sensitive: false } end
app/controllers/data_elements_controller.rb
def create # please add index `name` column , ensure unique 1 type = type.find_by(name: params[:type].to_s) if type.nil? head :unprocessable_entity else @data_element = dataelement.new(data_element_params.merge(type: type)) if @data_element.save #dosomething end end end
you might want refactor method bit, sure gives general idea.
Comments
Post a Comment