Rendering Liquid Template in Controller - ruby-on-rails

I'm trying to have the "show" action for my pages controller render a Liquid template instead of the normal view. The template itself is stored in the database.
This is my show action:
def show
#organization = Organization.find_by_subdomain(request.subdomain)
#template = Liquid::Template.parse(Template.find(#organization.current_template))
#page = #organization.pages.find(params[:id])
respond_to do |format|
format.html { render #template.render('page' => #page)}
format.json { render json: #page }
end
end
However, it raises this exception:
uninitialized constant PagesController::Liquid
I'm a RoR newbie, so I'm assuming what's happening is that it's trying to find the Liquid class in the PagesController class, instead of realizing it's a class unto itself. I'm following the (somewhat sparse) instructions here as best I can.
What am I doing wrong?

You need to include liquid in your Gemfile:
gem "liquid"
Then run bundle install and restart your rails server.

Related

Rendering issue for Facebook Crawlers - Ruby On Rails - Browser Gem

I'm developing a preview for facebook crawlers using browser gem .The problem is on rendering point . I don't know how to set the respond_to block in the controller . Currently , I've the following
def show_preview
#question = to_array(#question)
question_package = formatting_questoins(#question,params[:id].to_i)
#searched_question = question_package.first
respond_with do |format|
format.html { render 'show_preview' }
end
end
It renders nothing . I tried with
respond_with do |format|
format.html { render 'show_preview' }
format.json
end
But it also renders nothing . Any help will be appreciating
Rails knows which view to use for each controller action by convention. Your action show_preview of your controller MyController will use the view views/my_controller/show_preview.html.erb.
You do not need to use respond_with nor render for that.
So your controller action becomes :
def show_preview
#question = to_array(#question)
question_package = formatting_questoins(#question,params[:id].to_i)
#searched_question = question_package.first
end
And your view views/my_controller/show_preview.html.erb can now use #question and #searched_question in order to render something.
Documentation : http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-by-default-convention-over-configuration-in-action

Has controller action specific layouts changed in Rails 4.1

I've just upgraded to Rails 4.1.
I previously had the following in a controller action, which worked perfectly.
respond_to do |format|
format.html { render html: #user, layout: "fullscreen" }
end
This is not working in Rails 4.1, and the page simply renders the object #<User:0x007fb087429a70>
Edit the controller as follows fixes this error.
respond_to do |format|
format.html
end
What is the correct way to set the layout in Rails 4.1. I'm having trouble finding this in the docs.
html option was added in render method in Rails version 4.1. See the issue listed here
When you tried
def action_name
## ...
respond_to do |format|
format.html { render html: #user, layout: "fullscreen" }
end
end
in a Rails version prior to v4.1, what really happened was render ignored the html option, picked up the layout and went ahead to look for a view named action_name.html.***(where *** refers to template handler like erb, haml, etc). It found the view and rendered it. If the view didn't exist then you would have received a Missing template error
And when you use the same code in Rails 4.1, as the html option is allowed in render method it will definitely be processed. Now, first you need to understand what the html option actually does:
You can send a HTML string back to the browser by using the :html
option to render:
render html: "<strong>Not Found</strong>".html_safe
You use this when you don't want to write an html file for your action and wish to simply render a HTML string.
Which is the reason when this particular action is called you now see an html page with object #<User:0x007fb087429a70> because you passed the value to html option as #user.
Edit the controller as follows fixes this error.
respond_to do |format|
format.html
end
Firstly, it was not an error. You misinterpreted what html option does. I am pretty sure you do have a view corresponding to your action which is what you expected to be rendered. The above code does that for you.
I suppose you simply wish to specify layout for your view. All you need to do is:
respond_to do |format|
format.html { render layout: "fullscreen" }
end

show paperclip ( images) which stores in another app, current app already connect with the external database,Ruby on rails

I have a new app, and I want share the common part with another ror app.
For example, I have a MVC named showcase for showing images in the previous app, I want have the same one in my new app too.
Now I have connect my new app with the previous app's database, create a model with same name"showcase", and could get its columns like image_file_name; image_content_type;; image_file_size.. but in the view page for showcase in the new app, it can not recognize imagewhich is paperclip type attribute.
Can anyone tell me how can I use the images from the previous app?
Thanks a lot!
update:
class Showcase < ActiveResource::Base
self.site = "http://localhost:3000"
end
controller:
class ShowcasesController < ApplicationController
def index
#showcases = Showcase.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #showcases }
format.xml { render :xml => #showcases }
end
end
def show
#showcase = Showcase.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #showcase }
format.xml { render :xml => #showcases }
end
end
end
view:
<%= image_tag #showcase.image.url %
the error:
undefined method"image" for #
how could my view recognize image?
by the way in the original app, it didn't render xml, so I manually append render xml is that ok?
format.html # show.html.erb
format.json { render json: #showcase }
format.xml { render :xml => #showcases }
If you have a proper restful API to access the showcase resource in your first app(app1), then you can use the showcase model from the other ROR app(app2) ActiveResource. ActiveResource abstracts the communication between the two applications and it looks as though the model belonged to the same application.
If the restful url for showcase model in app1 is www.app1.com/showcases, then in the app2, all you have to do is create a model named showcase like below.
class ShowCase < ActiveResource:Base
self.site="www.app1.com"
end
Check out rails cast episode http://railscasts.com/episodes/94-activeresource-basics for more details.

Skip JSON format in rails generate scaffold

When you generate a rails scaffold using a command like rails g scaffold Thing is there any way to avoid getting that annoying
respond_to do |format|
format.html # index.html.erb
format.json { render json: #things }
end
stuff in your controller?
I'm trying to teach a class on Rails and I'd like to start by having them generate a scaffold, but with all the json formatting it's much more complicated than it needs to be. I'd be much happier if they could generate a scaffold that created a controller like this:
class ThingsController < ApplicationController
def index
#things = Thing.all
end
def show
#thing = Thing.find(params[:id])
end
def new
#thing = Thing.new
end
def edit
#thing = Thing.find(params[:id])
end
def create
#thing = Thing.new(params[:thing])
if #thing.save
redirect_to #thing, notice: 'Thing was successfully created.'
else
render: "new"
end
end
end
def update
#thing = Thing.find(params[:id])
if #thing.update_attributes(params[:thing])
redirect_to #thing, notice: 'Thing was successfully updated.'
else
render: "edit"
end
end
end
def destroy
#thing = Thing.find(params[:id])
#thing.destroy
redirect_to things_url
end
end
Comment out gem jbuilder in your Gemfile and respond_to blocks won't be generated.
Just clone the file
https://github.com/rails/rails/blob/v5.2.2/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
to your
lib/rails/generators/rails/scaffold_controller/templates/controller.rb
path in your application and customize what you want. Also, you can write your own generators for scaffolding ( http://guides.rubyonrails.org/generators.html ).
I think you'd be missing an opportunity. For one thing, you'd be teaching non-standard Rails, so your students might be confused when they see the normal version in their own installations.
More importantly, the controllers are formatted that way for a reason. Rails puts an emphasis on REST, which encourages access to resources via multiple data formats. Many modern apps are de-emphasizing slower server-rendered html/erb responses in favor of json APIs. I realize this is a little over a year after your OP, and you have limited time in class, just adding some thoughts for anyone who might happen by. I think you could wave your hand over the respond_to and tell them it's setting you up for some future possibilities.
You'll notice that the JSON response is coded directly into the template for the rails generator here:
https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
I think something to note is that the scaffold generator is really intended to illustrate and moreover educate on how the Rails stack works, it shows how you can edit the controller to provide many different formats to suit your needs!

Unitialized constant in model

I have a very simple model using Mongoid. I've added the use of Redcarpet to parse the MD and store it. However during update_attributes it is throwing an exception. Running the model and running the update through rails c works fine.
class Post
include Mongoid::Document
field :contents_markdown
field :contents
key :title
before_create :markdown
before_save :markdown
protected
def markdown
if self.contents_markdown
self.contents = Redcarpet.new(self.contents_markdown).to_html.html_safe
end
end
end
Here is the controller that blows up.
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
Here is the exception and stacktrace. The line numbers will be slightly off as I have removed stuff from the model.
uninitialized constant Post::Redcarpet
app/models/post.rb:20:in `markdown'
app/controllers/posts_controller.rb:62:in `block in update'
app/controllers/posts_controller.rb:61:in `update'
If it matters, I'm running MRI 1.9.2-p290 and Rails 3.1-rc5.
Edit -
This all works fine when running tests and running through the console. However going through the controller to update/create the model seems to always fail. Additionally from the stacktrace, you can see the model is in the standard location.
You might be missing a require or a gem declaration depending on how you're using Redcarpet.
The Rails auto-loader will generally catch these if that is defined in a standard location like app/models or, as is optional, lib/.
Usually you can fix this by putting the appropriate require statement in a config/initializers/redcarpet.rb type file, or altering your Gemspec as necessary.
You can try changing Redcarpet.newto ::Redcarpet.new which will tell Ruby to look for a top-level constant Redcarpet. I think that will likely fix it, but it's possible that the problem is something more complex.

Resources