According to current best practices a RESTful URL for a given thread on a message board should look something like this:
http://domain/forum/threads/3
It is also a common SEO practice that URLs should contain keywords (slug), so perhaps the above URL could become:
http://domain/forum/threads/3/title-of-this-particular-thread
Now, to edit this thread, again, according to the guidelines I've linked to in the first paragraph, the URL would be:
http://domain/forum/threads/3/edit
What should happen when someone starts a thread with the title of "edit"? How should it be decided if the thread is to be shown or edited?
Instead of http://domain/forum/threads/3/title-of-this-particular-thread
You should be doing http://domain/forum/threads/3-title-of-this-particular-thread
This will prevent conflicts and is just as SEO friendly. There are a few ways to accomplish this, but the easiest is to add a to_param method in your model that does the conversion automatically:
class Thread < ActiveRecord::Base
to_param
"#{id}-#{title}"
end
end
If you need more flexibility than this, or don't want to repeat it in all your models, you can use the friendly_id Gem.
Related
I need some help with the authorization. So far I was trying to solve it with the internal rails authorization combined with devise.
I have a user who is posting a request. If this request is private only a group of "reader" can see and answer the request. (This is number one)
Then the user give a rating to the answer of the reader. This should be accesible only for the user which received the answer and the "reader" who gave an answer.
So far I was using the following to limit access to the hidden requests:
before_filter :require_reader!, only: [:open_requests]
But if the request is not hidden, than still only the reader should be able to answer the request (but all can see it). Here I do not know how to manage this. Any Ideas?
To continue... I could not manage to solve the second problem (that the rating is seen only be the one who was placing the request and the reader).
Any ideas here?
Is cancancan maybe an option?
Best
witali
What you're doing does not quite follow the 'admin' pattern that's commonly setup with tools like Railsbricks. The 'admin' permissions pattern is typically a whole set of actions/views that are available only to admins, so often the entire Controller, or family of controllers, have the :require_admin! filter applied before every single action and view. Very simple permissions logic, and it depends only on the user and view.
Instead, what you've got is views with permissions that depend on your object's state as well as the user's status and the view. So you're going to have to write your own filter to use instead of using 'require_reader!'.
For example, you might have a RequestsController, and you could add to it:
before_action :must_be_able_to_view_request, except: [:index, :new, :create]
Then define that filter in the controller:
private
def must_be_able_to_view_request
if !current_user.is_reader? && !#request.ispublic
head :forbidden
end
end
If you need to use the same filter in other Controllers, then you can define it in your ApplicationController.
I'm looking for some advice on best practice in an MVC application. I can think of several ways of achieving what I want to achieve but I don't know what is considered best.
I am writing a discussion forum app and need to capture data from a URL to include in a post back from the page. I have links like this:
http://somedomain/Discussion/AddMessage/messageid/messagetitle
I need to include messageid and messagetitle in the form that is posted back on this page. What's the best way of going about this?
Ta! Mark
Your current url is more RPC, I would recommend reading about REST. I think a url like
http://somedomain/discussion/message
MessageId and MessageTitle are simply POST values.
http://www.codeproject.com/Articles/233572/Build-truly-RESTful-API-and-website-using-same-ASP
I do not find any way in order to modify the behaviour of the existing methods in rails_admin. I am using rails 3.2 and integrated with PostgreSql.
I want to modify the behaviour of one of my method during the edit. I have a model of shipment_quotes and model has a charges column, by default this field is blank and I want if admin add any amount in this field then after submitting the form a mail will be shoot to particular user.
But I have not found any way to modify the admin methods.
Also I want to create new actions for particular model.
Please help me I really fed up with this. After so much googling I do not find any thing relevant.
Any help will be really appreciated...
Rails Admin wouldn't do this for you. You might as well create a callback method for shipment_quotes after create. I think something like this would help
class ShipmentModel < ActiveRecord::Base
after_create :verify_charges
private
def verify_charges
if !charges.blank?
# Then shoot an email
end
end
end
Rails admin would then just handle your CRUD.
This is an incredibly newbish question, but I can't seem to find the answer.
I'm building an app that utilizes external APIs heavily, and I'm fairly new to Rails, so it's still a little rough to get around. I can't, for the life of me, figure out how to accept user input and execute a function in my app without writing to a model.
For example, I just want to let a user type in a Twitter username and have it display on the page. I know how to make a form to cache the search in a model, but I can't figure out how to just... make a function happen on a page. I've been breaking my brains on this for several days now.
Please help? :/
You don't need a model to use Rails, but if you don't need ActiveRecord at all, you might benefit from a lighter framework like Sinatra. That doesn't answer your question, but it's worth thinking about if you really have no database requirement for your application.
It sounds like you're just trying to access non-resourceful user input, which is accessible in the controller via the params hash. So, assuming you have set up a valid route for the form action, you use your controller to extract GET or POST parameters.
For example:
# You define a non-resourceful route in routes.rb for your form action.
get 'twitternames/show'
# Form action directs user to GET the following route after filling in the form.
http://example.com/twitternames/show?user=foo
# The controller action extracts the data.
def show
#user = params[:user]
# render the view unless you tell rails to do something else
end
# show.html.erb
<%= #user %>
Creating the right route is the key. Once you've defined a route that can break a URL into the proper segments, the rest will fall into place.
Is there a way to specify conditional statement inside routes.rb - I would like the root_path to depend on whether the user is signed in or not. perhaps there are other ways of accomplishing this?
Thanks!
Actually I think you can using advanced constraints it is documented here...
You would define a def matches?(request) to check if the user is signed in, and use two routes one when with a constraint of signed in and one when not.
Although I am not sure if the session is available when that custom constraint is executed.
Although I agree with SpyrosP it would be better to do it in the Controller.
No, you cannot do that. The routes do not rely on conditions that are based on model code. Anybody can call a route, so you cannot depend on that anyway.
Instead, just add a "before_filter :authenticate"(using sessions) on the controllers that you want to protect. If somebody tries to access your admin controller without being an admin, they will be redirected to login or anywhere you like.
I think the previous answers (suggesting a before_filter in the controller is more appropriate) are missing the OP's use case slightly. There are still advantages to doing it as a conditional route/advanced constraint. It doesn't replace having a before filter in the controller to prevent unauthorized direct access. But, for instance, having a redirect_to root_path route directly to e.g. a user's profile when he is signed in, or the front page when not, preserves flash messages that would otherwise be lost in a second redirect in the before filter. More elegant IMHO to use the advanced constraint approach (assuming of course that the session is in fact available when the custom contraint is tested). Not to mention, in this type of instance, why not save the extra redirect (since it involves a whole other HTTP(S) transaction)?
UPDATE:
If you're using Devise, this article describes an even better approach. Just implemented it myself and it works great, and it's clean.
Also, comments to explain down votes are always appreciated, not just for the author but for others who read the answer so they know why it might not be a reasonable response.