婚礼邀请函小程序由5个页面组成,分别是邀请函页面、照片页面、美好时光页面、婚礼地点页面、宾客信息页面。效果图如下:

下面针对5个页面的功能作简要介绍:
婚礼邀请函项目目录结构
| 路 径 | 说 明 |
|---|---|
| app.js | 应用程序的逻辑文件 |
| app.json | 应用程序的配置文件 |
| app.wxss | 定义公共样式 |
| pages/index/ | “邀请函”页面文件保存目录 |
| pages/picture | “照片”页面文件保存目录 |
在微信开发者工具中创建一个空白项目。创建成功后,新建 app.json文件,在该文件中定义本项目中的页面路径,代码如下:
{"pages": [
“pages/index/index”, // 邀请函页面
…
“pages/guest/guest“ // 宾客信息页面
]}
在app.json文件中定义项目导航栏样式,代码如下:
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#ff4c91",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": false
}
在app.json文件中定义项目底部标签栏,代码示例如下:
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "images/invite.png",
"selectedIconPath": "images/invite.png",
"text": "邀请函"
}…]
}
邀请函页面的任务需求如下:
页面结构图:

功能控制音频播放,小程序切入后台时,如果音频当前处于播放状态,可以继续播放。
index.wxml
<view class="player player-{{isPlayingMusic ? 'play' : 'pause'}}"
bindtap="play">
<image src="/images/music_icon.png" />
<image src="/images/music_play.png"/>
</view>
index.js
onReady: function () {
this.bgm = wx.getBackgroundAudioManager()
this.bgm.onCanplay(()=> {
this.bgm.pause()
})
this.bgm.src = this.music_url
},
index.js
play: function (e) {
if (this.data.isPlayingMusic) {
this.bgm.pause()
} else { this.bgm.play() }
this.setData({
isPlayingMusic:!this.data.isPlayingMusic })
},
效果如下:

index.wxml
<image class="content-gif" src= "/images/save_the_date.gif" />
<view class="content-title">邀请函</view>
<view class=“content-avatar">头像</view>
<view class="content-address">
<view>我们诚邀您来参加我们的婚礼</view>
<view>时间:2019年1月28日</view>
<view>地点:北京市海淀区XX路XX酒店</view>
</view>
效果如下:

页面内各元素的高度应满屏显示,为此,推荐使用viewport单位,即通过vw和vh表示宽度和高度,确保.content内部的元素高度加起来不超过100。
index.wxml
<view class="content-info">
<view bindtap="callGroom">
<view bindtap="callBride">
</view>
callGroom: function () {wx.makePhoneCall({})},
callBride: function () {wx.makePhoneCall({})}

在本任务中,将会完成照片页面的开发,该页面采用纵向轮播的方式展示图片,可以通过单击指示面板的圆点切换到相对应的图片。
功能需求如下:
页面结构图:

picture.wxml
<swiper indicator-color="white" indicator-active-color="#ff4c91"
indicator-dots autoplay interval="3500" duration="1000" vertical circular>
<swiper-item wx:for="{{imgUrls}}" wx:key="*this">
<image src="{{item}}" mode="aspectFill" />
</swiper-item>
</swiper>
picture.wxss
swiper { height: 100vh; }
image { width: 100vw; height: 100vh; }
设置swiper组件属性:指示点默认颜色为白色,当前指示点颜色为 #ff4c91,轮播图方向通过 vertical设置为纵向,autoplay 开启自动轮播,circular 开启无缝轮播,duration 滑动动画时长为1秒,interval自动切换时间为3.5秒。
picture.js
data: {
imgUrls: [
'/images/timg1.jpg', '/images/timg2.jpg',
'/images/timg3.jpg', '/images/timg4.jpg'
]
}
效果图如下:

在本任务中,将会完成美好时光页面的开发,该页面采用视频的方式来记录一对新人的难忘时光。
任务需求如下:
项目结构图:

video 组件常用属性
| 名称 | 类型 | 说明 |
|---|---|---|
| src | String | 视频的资源地址 |
| loop | Boolean | 是否循环播放,默认为flase |
| controls | Boolean | 是否显示默认播放控件(播放/暂停按钮、播放进度、时间),默认为true |
| danmu-list | Object | 弹幕列表 |
| danmu-btn | Boolean | 是否显示弹幕显示/隐藏按钮,只在初始化时有效,不能动态变更,默认为false |
| enable-danmu | Boolean | 是否展示弹幕,只在初始化时有效,不能动态变更,默认为false |
| autoplay | Boolean | 是否自动播放,默认为false |
| poster | String | 视频封面的图片网络资源地址,如果controls属性值为false,则设置poster无效 |
| bindplay | EventHandle | 当开始/继续播放时触发play事件 |
| bindpause | EventHandle | 当暂停播放时触发pause事件 |
video.wxml
<video id="myVideo" src="{{src}}" danmu-list="{{danmuList}}"
enable-danmu danmu-btn controls></video>
<input bindblur="bindInputBlur" />
<button bindtap="bindSendDanmu">发送弹幕</button>
video.js
data: {
src: 'http://……/xxx.mp4',
danmuList: [{ text: '第 1s 出现的弹幕', color: '#ff0000', time: 1 },
{ text: '第 3s 出现的弹幕', color: '#ff00ff', time: 3 }] },
onReady: function () { this.videoContext = wx.createVideoContext('myVideo')}
关键函数:
bindInputBlur()函数
bindSendDanmu()函数
video.js
videoContext = null,
inputValue: '',
bindInputBlur: function (e) {
this.inputValue = e.detail.value
},
bindSendDanmu: function () {
this.videoContext.sendDanmu({
text: this.inputValue,
color: '#f90'
})
video组件示例图:37

VideoContext 对象常用方法如下:
| 名称 | 说明 |
|---|---|
| play() | 播放视频 |
| pause() | 暂停视频 |
| stop() | 停止视频 |
| seek(number) | 跳转到制定的位置 |
| plavbackRate(number) | 设置倍数播放 |
| requestFullScreen | 进入全屏 |
| exitFullScreen | 退出全屏 |
video.wxml
<button bindtap="bindButtonTap">获取视频</button>
video.js
bindButtonTap: function() {
wx.chooseVideo({
sourceType: ['album', 'camera'], // 视频选择的来源,相册和相机
maxDuration: 60, // 拍摄视频最长拍摄时间(秒)
camera: 'back', // 默认拉起的是前置(front)或者后置(back)摄像头
success: res => {// 成功时执行的回调函数
this.setData({src: res.tempFilePath// 选定视频的临时文件路径}) }})
},
video.wxml
<view class="video-list" wx:for="{{movieList}}" wx:key="user">
<view class="video-title">标题:{{item.title}}</view>
<view class="video-time">时间:{{item.create_time}}</view>
<video src="{{item.src}}" objectFit="fill"></video>
</view>
video.wxss
.video-list {
box-shadow: 0 8rpx 17rpx 0 rgba(7, 17, 27, 0.1);
margin: 10rpx 25rpx; padding: 20rpx; border-radius: 10rpx;
margin-bottom: 30rpx; background: #fff;
}
video.js
data: {
movieList: [{
create_time: '2018-7-25 19:55:54', title: '海边随拍',
src: 'http://……/xxx.mp4'
}, {
create_time: '2018-7-25 19:56:17', title: '勿忘心安',
src: 'http://……/xxx.mp4'
}] }
效果如下:

WXS应用场景举例:
页面中data数据来自服务器端,但可能不适合直接显示到页面中,需要对数据进行转换后才能显示。
例如接收到的时间字段为时间戳。
假设在本项目中,视频列表数据是从服务器获取的,服务器返回的create_time是一个时间戳,下面在pages/video/video.js文件中模拟这一情况,将 create_time改为时间戳
video.js
create_time:1532519777690,
wxs脚本语言嵌入代码
<wxs module="formatData">
module.exports = function(timestamp) {
var date = getDate(timestamp)
…
var h = date.getHours()
return y + '-' + m + '-' + d + ' ' + h}
</wxs>
在本任务中,将会完成婚礼地点页面的开发,该页面会显示婚礼地点的地图,单击导航图标可以定位酒店位置,查看路线。
功能需求如下:
婚礼地点运行效果图:

map组件常用属性如下:
| 名称 | 类型 | 说明 |
|---|---|---|
| longitude | Number | 经度 |
| latitude | Numberr | 纬度 |
| scale | Number | 缩放级别,取值范围是5~18,默认16 |
| markers | Array | 标记点 |
| polyline | Array | 路线 |
| circles | Array | 圆 |
| show-location | Boolean | 显示有带方向的当前定位点 |
| bindmarkertap | EvenHandle | 电机标记点时触发,会返回marker的id |
| bindregionchange | EvenHandle | 视野发生变化时触发 |
| bindtap | EvenHandle | 单击地图时触发 |
| bindupdated | EvenHandle | 在地图渲染更新完成时触发 |
markers 标记点属性如下:
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Number | 否 | 标记点id,marker单击事件回调会返回此id |
| longitude | Number | 是 | 经度,浮点数,范围-180~180 |
| latitude | Number | 是 | 纬度,浮点数,范围-90~90 |
| title | String | 否 | 标注点名 |
| zIndex | Number | 否 | 显示层级 |
| iconPath | String | 是 | 显示图标,使用项目目录下的图片路径 |
| rotate | Number | 否 | 顺时针旋转的角度,范围0~360,默认0 |
| alpha | Number | 否 | 透明度,范围0~2,默认为1(不透明) |
| width | Number | 否 | 图片宽度,默认图片实际宽度 |
| height | Number | 否 | 图片高度,默认物品实际高度 |
| id | Number | 否 | 标记点id,marke单击事件回调会返回此id |
polyline 坐标点的属性如下:
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
| points | Array | 是 | 经纬度数组,如 [{latitude:0,longitude:0}] |
| color | String | 否 | 线的颜色,8位十六进制表示,后两位表示alpha值,如:#000000AA |
| width | Number | 否 | 线的宽度 |
| dottedLine | Boolean | 否 | 是否虚线,默认为false |
circles 圆的属性如下:
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
| latitude | Number | 是 | 纬度,浮点数,范围-90~90 |
| longitude | Number | 是 | 经度,浮点数,范围-180~180 |
| color | String | 否 | 描边颜色8位十六进制表示,后两位表示alpha值,如:#0000000AA |
| fillColor | String | 否 | 填充颜色8位十六进制表示,后两位表示alpha值,如:#0000000AA |
| radius | Number | 是 | 半径 |
获取经纬度: map组件需要给定经纬度,下面通过腾讯位置服务网站提供的坐标拾取器(https://lbs.qq.com/tool/getpoint/)来获取,示例图
如下:

map.wxml
<map latitude="40.060148" longitude="116.343219" scale="18" />
小程序提供了打开微信内置地图的API和定位用户位置的API,需要用户授权才能使用,也就是会自动提示用户“是否同意获取您的位置”,同意后即可获取。
map.wxml
<button bindtap="buttonTap">查看我的位置</button>
map.js
buttonTap: function() {
wx.getLocation({
type: 'gcj02',
success: function (res) {
wx.openLocation({
latitude: res.latitude,
longitude: res.longitude }) }
}) }
保存上述代码,在手机中运行测试,单击按钮后,得到效果图如下:

map.wxml
<map latitude="{{latitude}}" longitude="{{longitude}}" markers="{{markers}}" bindmarkertap="markertap" />
map.wxss
map { width: 100vw; height: 100vh; }
map.js
data: {
latitude: 40.06021, longitude: 116.3433,
markers: [{
iconPath: '/images/navi.png', id: 0,
latitude: 40.06021, longitude: 116.3433, width: 50, height: 50
}] },
markertap: function() {
wx.openLocation({
latitude: this.data.latitude, longitude: this.data.longitude,
}) }
在本任务中,将会完成宾客信息页面的开发,该页面提供了一个表单,用于填写来宾的信息,包括姓名、手机号、参加婚礼人数、新人祝福语。
功能需求如下:
页面结构图:

picker组件是从底部弹起的滚动选择器,目前支持5种选择器,通过mode属性来区分。
选择器类型如下:
guest.wxml
<picker range="{{array}}" value="{{index}}" bindchange="pickerChange">
<view>当前选择:{{array[index]}}(点我修改)</view>
</picker>
guest.js
data: { array: ['HTML', 'CSS', 'JavaScript', 'Photoshop'],
index: 1 },
pickerChange: function(e) {
this.setData({ index: e.detail.value })
},
range属性表示显示在底部选择器的列表数组,数组中的每一个元素对应列表中的每一项;value属性表示当前选择了range数组中的某个元素的下标,默认值为0。bindchange用于绑定change事件,该事件会在value改变时触发。
保存上述代码,运行程序测试,页面效果图如下:

模板消息 是在小程序中向用户发送消息的一种方式,其特点是必须按照小程序提供的模板来给用户发送消息,而且小程序在审核时,会对消息的标题、关键字等进行审查,以免功能被恶意使用。
使用场景如下:
支付提醒:当支付成功时会推送给用户成功支付的信息,告知用户的订单详情。到账提醒:红包退还到账提醒、收款到账提醒等。广告推送: 如订阅号推送、公众号推送等。模板消息使用步骤:
进入小程序管理后台,单击左侧菜单中的 “模板消息”,
然后单击“添加”按钮添加模板:

在模板库中搜索模板,例如,搜索“婚礼”,示例图如下:

在搜索结果列表中,选择“婚礼请帖回复通知”,单击“选用”,即可选用该模板。选用成功后,可以查看该模板的ID和关键词:

模板消息使用注意事项:
实际开发中,模板消息的发送一般是由服务器主动发送给曾经使用过这个小程序的用户。
小程序本身不具备接收消息的功能,是由微信中的服务通知功能将消息转达给用户。
Q : 如何证明用户使用过某个小程序?
(必须满足以下其中一个条件):
支付:用户在小程序内完成过支付行为,可允许开发者向用户在7天内推送有限条数的模板消息,1次支付可以发3条消息。
提交表单:当用户在小程序内发生过提交表单行为,且该表单声明为要发模板消息,开发者需要向用户提供服务时,可允许开发者向用户在7天内推送有限条数的模板消息,1次提交表单可下发1条。
guest.wxml
<form bindsubmit="formSubmit" >
<input name="name" placeholder="输入您的姓名" />
<input name="phone" placeholder="输入您的手机号码" />
<picker name="num" bindchange="pickerChange" value="{{picker.index}}" range="{{picker.arr}}">参加婚礼人数:{{picker.arr[picker.index]}}</picker>
<input name="wish" placeholder="输入您的祝福语" />
<button form-type="submit">提交</button>
</form>
guest.js
data: {
picker: {
arr: ['0', '1', '2', '3', '4', '5', '6'],
index: 1
} },
pickerChange: function (e) {
this.setData({
'picker.index': e.detail.value
})
}
效果图如下:

准备页面:pages/guest/guest.wxml,绑定blur事件,校验输入格式是否正确。
<view>
<input name="name" bindblur="nameChange"
placeholder-class="phcolor" placeholder="输入您的姓名" />
</view>
<view>
<input name="phone" bindblur="phoneChange"
placeholder-class="phcolor" placeholder="输入您的手机号码" />
</view>
pages/guest/guest.js,编写check ()函数
check: function(data, reg, errMsg) {
if (!reg.test(data)) {
wx.showToast({title: errMsg, icon: 'none', duration: 1500})
return false
}
return true
}
pages/guest/guest.js,编写checkName()函数、checkPhone()函数
checkName: function(data) {
var reg = /^[\u4E00-\u9FA5A-Za-z]+$/;
return this.check(data, reg, '姓名输入错误!')
},
checkPhone: function(data) {
var reg = /^(((13)|(15)|(17)|(18))\d{9})$/
return this.check(data, reg, '手机号码输入有误!')
},
pages/guest/guest.js,编写事件处理函数nameChange()、phoneChange() 函数。
nameChange: function (e) {
this.checkName(e.detail.value)
},
phoneChange: function (e) {
this.checkPhone(e.detail.value)
},
pages/guest/guest.js,编写提交表单事件formSubmit()函数。
formSubmit: function(e) {
var name = e.detail.value.name
var phone = e.detail.value.phone
if (this.checkName(name) && this.checkPhone(phone)) {
// 在此处可编写代码将e.detail.value提交到服务器
wx.showToast({title: '提交成功', icon: 'success', duration: 1500})
}
}
发送模板消息功能涉及到3个角色的参与,分别是小程序、服务器和微信接口,具体交互流程如下:
formId和code,提交给服务器。appid、secret和code请求微信接口,获 openid。appid、secret请求微信接口,获取access_token,然后使用access_token和openid、formId,以及模板的id和消息内容请求微信接口,发送模板消息。pages/guest/guest.wxml,为提交按钮设置report-submit属性,生成formId。
<button form-type="submit" report-submit>提交</button>
pages/guest/guest.js,在formSubmit()函数里,输出formId。
formSubmit: function(e) {
console.log(e.detail.formId)
……(原有代码)
}
注意事项: 在微信开发者工具中formId的输出结果为“the formId is a mock one”,表示formId是模拟的;在微信环境下运行小程序时,才可以获取到formId。
formId控制台打印结果如下图:

服务器端代码:pages/guest/guest.js文件
在Page()函数后面编写server对象,用于模拟服务器,与微信接口进行交互:
var server = {
appid: '', secret: '',
user: {openid: '', formId: ''}, // 用于保存用户的openid和formId
// 用于接收表单,调用this.getOpenid()根据code换取openid
post: function(data, success) {}, ...
}
在小程序管理后台获取appid和secret,appid对应AppId,secret对应AppSecret。

服务器端代码: pages/guest/guest.js文件
在formSubmit()表单验证成功的if判断中,编写代码请求服务器。
if (this.checkName(name) && this.checkPhone(phone)) {
wx.login({
success: res => { // 将表单提交给服务器,传入formId和code
server.post({ formId: e.detail.formId, code: res.code }, ()=> {
wx.showToast({title: '提交成功!', icon: 'success', duration: 1500}) // 提交成功后,由服务器发送模板消息
server.sendTemplateMessage(res => { console.log('消息发送结果:', res.data)})
}) }
}) }
在server对象中编写post()方法。
post: function(data, success) {
console.log('收到客户端提交的数据:', data)
this.user.formId = data.formId
this.getOpenid(data.code, res => {
console.log('用户openid:' + res.data.openid)
this.user.openid = res.data.openid
success()
})
},
在server对象中编写getOpenId()方法。
// 用于根据code获取openid
getOpenid: function(code, success) {
wx.request({
url: 'https://api.weixin.qq.com/sns/jscode2session',
data: { appid: this.appid, secret: this.secret,
grant_type: 'authorization_code', js_code: code },
success: success
})
},
在server对象中编写sendTemplateMessage()函数。
// 用于发送模板消息
sendTemplateMessage: function(success) {
var user = this.user
var data = { touser: user.openid, page: 'index', form_id: user.formId,
template_id: 'vKLdyH1bJ8aXFZrZ-kgrYA58dcf8OCd5DDPN0QbXPhM',
data: { keyword1: { value: '王辉辉、张琳琳' },
keyword2: { value: '谢谢你的祝福' },
…}
}
在server对象中编写sendTemplateMessage()函数。
this.getAccessToken(res => {
var token = res.data.access_token
console.log('服务器access_token:' + token)
var url = 'https://api.weixin.qq.com/
cgi-bin/message/wxopen/template/send?
access_token=' + token
wx.request({ url: url, method: 'post',
data: data, success: success })
})
},
在server对象中编写getAccessToken()函数。
// 用于获取access_token
getAccessToken: function(success) {
var url = 'https://api.weixin.qq.com/
cgi-bin/token?
grant_type=client_credential&appid=' + this.appid
+ '&secret=' + this.secret
wx.request({ url: url, success: success })
}
宾客信息页面提交表单后就会收到微信的提示信息“婚礼请帖回复通知”:

本项目通过一个婚礼邀请函的设计,讲解了小程序中的 标签页切换、背景音乐API、拨打电话API、video组件、腾讯视频插件、map组件、地图定位API、WXS、picker组件,以及模板消息的使用。能够熟练在小程序中灵活使用各种组件完成具体功能,掌握音频播放、视频播放、地图定位、模板消息等常见开发需求的实现。
婚礼邀请函小程序
本人在CSDN论坛写的所有文章,仅针对本人自身做学习记录,不全面,不详细,还请见谅!
如果有小伙伴需要详细解答或完整学习资源, 欢迎加入我的知识星球「Naiva的知识问答社区」
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R