0

I'm playing with Ruby on Rails for the first time, and have an app up and running. Here's the quick database definition:

Teams
- id: int
- name: char[20]

Answers
- id: int
- answer_value: text

I want to be able to type: "http://localhost:3000/teams/1/answers/purple" in a browser if team 1 answers purple.

I thought that adding the following to my routes.rb file would allow me to do that, but it hasn't.

resources :teams do
  resources :answers
  post 'answer_value', :on => :member
end

I can see the first answer by team 1 by going to "http://localhost:3000/teams/1/answers/1" , but I don't know how to actually set values via the URI.

Mischa
  • 42,876
  • 8
  • 99
  • 111

4 Answers4

0

If I understand you correctly, in you answers controller's show action, instead of doing Answer.find(params[:id]), do Answer.find_by_answer_value(params[:id])

Chirantan
  • 15,304
  • 8
  • 49
  • 75
  • I think we're getting close with this answer. I didn't realize that the function that accepts the URL I used in my original question was the show action in the answers controller. I believe I need to change that to Answer.new(params[:id]) though, not Answer.find_by_answer_value. I'm not looking up a previous answer, I'm trying to create another one. Now, I'm running into 'undefined method `stringify_answers' for "":String'... Where do I find the correct way to call new? – Ryan Lamb Jul 17 '12 at 09:56
  • Just to clarify, I'm trying to set the value with the URL, not look up a previously created answer – Ryan Lamb Jul 17 '12 at 10:09
0

If you want to create an answer, please post to

/teams/1/answers

with parameter :answer => { :answer_value => 'purple' }

Don't append answer_value to the url, looks like it's record id.

Prajna
  • 1,217
  • 11
  • 10
  • Thanks for the quick response! Is there no way to set up Ruby on Rails to expect the answer_value on the url instead of the record ID? – Ryan Lamb Jul 17 '12 at 09:44
  • Of course there is. But I do suggest you follow the rails way, with gems like inherit_resources you don't even need to write any code in the controllers. – Prajna Jul 19 '12 at 11:16
0

You need to either over ride the to_param method in the model, which can do what you are looking for although there are some caveats - including needing to use what @Chirantan suggested with Answer.find_by_answer_value(params[:id]) for all your finders. You can find more info in this Railscast on the subject or search for to_param in the Rails API and select the entry under ActiveRecord::Integration.

Alternatively you can go with a gem like FriendlyId which provides some more comprehensive functionality and control over the URL construction.

nmott
  • 9,454
  • 3
  • 45
  • 34
0

Typing things into your browser won't perform a post, regardless of what you put in the routes, it will only perform a get. Creating something by a get is not RESTful, and you really shouldn't do it. That said, since you say you're just 'playing around with rails', you could do this:

If you want a get to create the thing, you have to set it that way in the routes. /teams/1/answers/purple

get '/teams/:team_id/answers/:answer_value' => 'answers#create'

then in your answers controller, create action, you could just check for a params[:team_id] and params[:answer value] and make sure that gets set before the save.

def create
  @answer = Answer.new()
  @answer.team_id=params[:team_id]
  @answer.answer_value=params[:answer_value]


  respond_to do |format|
    if @answer.save
      format.html { redirect_to @answer, notice: 'Answer was successfully created.' }
      format.json { render json: @answer, status: :created, location: @answer }
    else
      format.html { render action: "new" }
      format.json { render json: @answer.errors, status: :unprocessable_entity }
    end
  end
end
Nate914375
  • 182
  • 3
  • 4