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