tommyd456
tommyd456

Reputation: 10673

Rails and Validation

I'm still (for those that have helped before) having issues validating data.

The Scenario

I have two models - user and accommodation with each user having one accommodation (has_one). I am able to access the logged in user using current_user.

The Problem

When I validate users upon registration everything works fine with validation error messages displayed accordingly for each validation rule. However, I am now trying to validate accommodations when they are entered and I get a Rails error page:

Unknown Action

The action 'show' could not be found for AccommodationsController

but interestingly the url has changed to /accommodations//edit which appears to be missing an id for the accommodations id (I do want it to divert to edit if everything is ok).

I don't think it's the validation rules themselves but more how I am handling redirection (which is confusing me to be honest!). The data saves correctly and redirects correctly if it passes the validation rules but not sure how to handle a "non-save" gracefully.

The Code

Accommodation Model

class Accommodation < ActiveRecord::Base
  belongs_to :user

  #validation rules
  validates :user_id, presence: true
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: {    case_sensitive: false }
end

/accommodations/new.html.erb

...
<%= form_for :accommodation, url: accommodations_path do |f| %>

<% if @accommodation.errors.any? %>
  <% @accommodation.errors.full_messages.each do |msg| %>
    <p class="error"><%= msg %></p>
  <% end %>
<% end %>

...

AccommodationsController (thanks to @depa for help with this)

...
def index
  if current_user.accommodation.present?
    redirect_to edit_accommodation_path(current_user.accommodation)
  else
    redirect_to new_accommodation_path(current_user.accommodation)
  end
end

def new
  @accommodation = Accommodation.new
end

def create
  current_user.create_accommodation(accommodation_params)
  flash[:success] = "Accommodation details added"
  redirect_to edit_accommodation_path(current_user.accommodation)
end

def edit
end

def update 
  if @accommodation.update(accommodation_params)
    flash[:success] = "Accommodation details updated successfully"
    redirect_to edit_accommodation_path(@accommodation)
  else
    flash[:error] = "Accommodation details could not be updated"
    render 'edit'
  end
end

private
  def accommodation_params
    params.require(:accommodation).permit(:name, :email)
  end
...

Upvotes: 0

Views: 96

Answers (2)

veritas1
veritas1

Reputation: 9170

To handle your failed validations gracefully:

def create
  @accommodation = current_user.build_accommodation(accommodation_params)
  if @accommodation.save
    flash[:success] = "Accommodation details added"
    redirect_to edit_accommodation_path(current_user.accommodation)
  else
    flash.now.notice = "Error creating accommodation"
    render "new"
  end
end

Upvotes: 1

Chowlett
Chowlett

Reputation: 46667

Is accommodation_params actually set up on entry to create? I'd expect you to need to use params or params[:accommodation].

If it isn't, the create_accommodation call is going to fail, which will mean current_user.accommodation will be nil, which may well produce your error.

Upvotes: 0

Related Questions